1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 10:46:35 +01:00

[FTP] Added support for non-latin names for dir/file.

This commit is contained in:
S. Razi Alavizadeh 2013-02-13 19:49:29 +03:30
parent 1059936d57
commit 9951d2e69b
5 changed files with 116 additions and 88 deletions

View File

@ -111,86 +111,6 @@ void DownloadFileHelper::handleUnsupportedContent(QNetworkReply* reply, const Do
}
}
// http://stackoverflow.com/questions/1031645/how-to-detect-utf-8-in-plain-c
static bool isUtf8(const char* string)
{
if (!string) {
return 0;
}
const unsigned char* bytes = (const unsigned char*)string;
while (*bytes) {
if ((// ASCII
bytes[0] == 0x09 ||
bytes[0] == 0x0A ||
bytes[0] == 0x0D ||
(0x20 <= bytes[0] && bytes[0] <= 0x7F)
)
) {
bytes += 1;
continue;
}
if ((// non-overlong 2-byte
(0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF)
)
) {
bytes += 2;
continue;
}
if ((// excluding overlongs
bytes[0] == 0xE0 &&
(0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
) ||
(// straight 3-byte
((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
bytes[0] == 0xEE ||
bytes[0] == 0xEF) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
) ||
(// excluding surrogates
bytes[0] == 0xED &&
(0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
)
) {
bytes += 3;
continue;
}
if ((// planes 1-3
bytes[0] == 0xF0 &&
(0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
) ||
(// planes 4-15
(0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
) ||
(// plane 16
bytes[0] == 0xF4 &&
(0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
)
) {
bytes += 4;
continue;
}
return false;
}
return true;
}
QString DownloadFileHelper::parseContentDisposition(const QByteArray &header)
{
QString path;
@ -201,7 +121,7 @@ QString DownloadFileHelper::parseContentDisposition(const QByteArray &header)
QString value;
if (isUtf8(header.constData())) {
if (QzTools::isUtf8(header.constData())) {
value = QString::fromUtf8(header);
}
else {

View File

@ -110,7 +110,7 @@ void FtpSchemeReply::processCommand(int id, bool err)
m_ftp->list();
}
else {
m_ftpCdId = m_ftp->cd(url().path());
m_ftpCdId = m_ftp->cd(QString::fromLatin1(QByteArray::fromPercentEncoding(url().path().toUtf8())));
}
break;
@ -122,6 +122,13 @@ void FtpSchemeReply::processCommand(int id, bool err)
if (m_isGoingToDownload) {
foreach(const QUrlInfo & item, m_items) {
if (item.isFile() && item.name() == m_probablyFileForDownload) {
QByteArray decodedUrl = QByteArray::fromPercentEncoding(url().toString().toUtf8());
if (QzTools::isUtf8(decodedUrl.constData())) {
m_request.setUrl(QUrl(QString::fromUtf8(decodedUrl)));
}
else {
m_request.setUrl(QUrl(QString::fromLatin1(decodedUrl)));
}
emit downloadRequest(m_request);
abort();
break;
@ -145,8 +152,13 @@ void FtpSchemeReply::processCommand(int id, bool err)
}
}
void FtpSchemeReply::processListInfo(const QUrlInfo &urlInfo)
void FtpSchemeReply::processListInfo(QUrlInfo urlInfo)
{
QByteArray nameLatin1 = urlInfo.name().toLatin1();
if (QzTools::isUtf8(nameLatin1.constData())) {
urlInfo.setName(QString::fromUtf8(nameLatin1));
}
m_items.append(urlInfo);
}
@ -247,7 +259,16 @@ QString FtpSchemeReply::loadDirectory()
}
QString page = sPage;
page.replace(QLatin1String("%TITLE%"), tr("Index for %1").arg(url().toString()));
QByteArray titleByteArray = QByteArray::fromPercentEncoding(url().toString().toUtf8());
QString title;
if (QzTools::isUtf8(titleByteArray.constData())) {
title = QString::fromUtf8(titleByteArray);
}
else {
title = QString::fromLatin1(titleByteArray);
}
page.replace(QLatin1String("%TITLE%"), tr("Index for %1").arg(title));
QString upDirDisplay = QLatin1String("none");
QString tBody;
@ -334,12 +355,18 @@ void FtpSchemeReply::ftpReplyErrorHandler(int id)
}
QStringList sections = url().path().split(QLatin1Char('/'), QString::SkipEmptyParts);
if (!sections.isEmpty()) {
m_probablyFileForDownload = sections.takeLast();
QByteArray lastSection = QByteArray::fromPercentEncoding(sections.takeLast().toUtf8());
if (QzTools::isUtf8(lastSection.constData())) {
m_probablyFileForDownload = QString::fromUtf8(lastSection);
}
else {
m_probablyFileForDownload = QString::fromLatin1(lastSection);
}
}
if (!m_probablyFileForDownload.isEmpty()) {
m_isGoingToDownload = true;
QString parentOfPath = QString("/%1/").arg(sections.join(QLatin1String("/")));
m_ftpCdId = m_ftp->cd(parentOfPath);
m_ftpCdId = m_ftp->cd(QString::fromLatin1(QByteArray::fromPercentEncoding(parentOfPath.toUtf8())));
}
else {
abort();
@ -368,7 +395,7 @@ FtpDownloader::FtpDownloader(QObject* parent)
void FtpDownloader::download(const QUrl &url, QIODevice* dev)
{
m_url = url;
m_url = QUrl(QString::fromLatin1(QByteArray::fromPercentEncoding(url.toString().toUtf8())));
m_dev = dev;
QString server = m_url.host();
if (server.isEmpty()) {

View File

@ -65,7 +65,7 @@ protected:
private slots:
void processCommand(int id, bool err);
void processListInfo(const QUrlInfo &urlInfo);
void processListInfo(QUrlInfo urlInfo);
void processData();
QString loadDirectory();
void loadPage();

View File

@ -362,6 +362,86 @@ QIcon QzTools::iconFromFileName(const QString &fileName)
return icon;
}
// http://stackoverflow.com/questions/1031645/how-to-detect-utf-8-in-plain-c
bool QzTools::isUtf8(const char* string)
{
if (!string) {
return 0;
}
const unsigned char* bytes = (const unsigned char*)string;
while (*bytes) {
if ((// ASCII
bytes[0] == 0x09 ||
bytes[0] == 0x0A ||
bytes[0] == 0x0D ||
(0x20 <= bytes[0] && bytes[0] <= 0x7F)
)
) {
bytes += 1;
continue;
}
if ((// non-overlong 2-byte
(0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF)
)
) {
bytes += 2;
continue;
}
if ((// excluding overlongs
bytes[0] == 0xE0 &&
(0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
) ||
(// straight 3-byte
((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
bytes[0] == 0xEE ||
bytes[0] == 0xEF) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
) ||
(// excluding surrogates
bytes[0] == 0xED &&
(0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
)
) {
bytes += 3;
continue;
}
if ((// planes 1-3
bytes[0] == 0xF0 &&
(0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
) ||
(// planes 4-15
(0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
) ||
(// plane 16
bytes[0] == 0xF4 &&
(0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
)
) {
bytes += 4;
continue;
}
return false;
}
return true;
}
// Qt5 migration help functions
bool QzTools::isCertificateValid(const QSslCertificate &cert)
{

View File

@ -57,6 +57,7 @@ QPixmap QT_QUPZILLA_EXPORT createPixmapForSite(const QIcon &icon, const QString
QString QT_QUPZILLA_EXPORT applyDirectionToPage(QString &pageContents);
QIcon QT_QUPZILLA_EXPORT iconFromFileName(const QString &fileName);
bool QT_QUPZILLA_EXPORT isUtf8(const char* string);
QString QT_QUPZILLA_EXPORT buildSystem();