From aeea26b384a362e59c335f7932a8b3915c1c8383 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Wed, 11 Nov 2009 14:56:41 +0100 Subject: QUrl::fromUserInput: improvements, corrections and make the demo browser use it. - Handle windows files names by looking for paths first (and don't check that it exists first) - Handle host names without dots (it was not handled because of difficulties with the case host:port) - Return the parsed url only if the host or the path is not empty instead of returning a url that looks like "http:" Reviewed-by: Thiago Macieira --- demos/browser/browsermainwindow.cpp | 43 +------------------------------------ demos/browser/browsermainwindow.h | 1 - src/corelib/io/qurl.cpp | 43 +++++++++++++++++++------------------ tests/auto/qurl/tst_qurl.cpp | 8 +++++-- 4 files changed, 29 insertions(+), 66 deletions(-) diff --git a/demos/browser/browsermainwindow.cpp b/demos/browser/browsermainwindow.cpp index fba3ac5..8e3986b 100644 --- a/demos/browser/browsermainwindow.cpp +++ b/demos/browser/browsermainwindow.cpp @@ -552,47 +552,6 @@ void BrowserMainWindow::slotViewStatusbar() m_autoSaver->changeOccurred(); } -QUrl BrowserMainWindow::guessUrlFromString(const QString &string) -{ - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Check if it looks like a qualified URL. Try parsing it and see. - bool hasSchema = test.exactMatch(urlStr); - if (hasSchema) { - QUrl url = QUrl::fromEncoded(urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - - // Might be a file. - if (QFile::exists(urlStr)) { - QFileInfo info(urlStr); - return QUrl::fromLocalFile(info.absoluteFilePath()); - } - - // Might be a shorturl - try to detect the schema. - if (!hasSchema) { - int dotIndex = urlStr.indexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString prefix = urlStr.left(dotIndex).toLower(); - QByteArray schema = (prefix == QLatin1String("ftp")) ? prefix.toLatin1() : QByteArray("http"); - QUrl url = - QUrl::fromEncoded(schema + "://" + urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - } - - // Fall back to QUrl's own tolerant parser. - QUrl url = QUrl::fromEncoded(string.toUtf8(), QUrl::TolerantMode); - - // finally for cases where the user just types in a hostname add http - if (url.scheme().isEmpty()) - url = QUrl::fromEncoded("http://" + string.toUtf8(), QUrl::TolerantMode); - return url; -} - void BrowserMainWindow::loadUrl(const QUrl &url) { if (!currentTab() || !url.isValid()) @@ -873,7 +832,7 @@ void BrowserMainWindow::slotSwapFocus() void BrowserMainWindow::loadPage(const QString &page) { - QUrl url = guessUrlFromString(page); + QUrl url = QUrl::fromUserInput(page); loadUrl(url); } diff --git a/demos/browser/browsermainwindow.h b/demos/browser/browsermainwindow.h index f5c14ea..f0f95b1 100644 --- a/demos/browser/browsermainwindow.h +++ b/demos/browser/browsermainwindow.h @@ -68,7 +68,6 @@ public: QSize sizeHint() const; public: - static QUrl guessUrlFromString(const QString &url); TabWidget *tabWidget() const; WebView *currentTab() const; QByteArray saveState(bool withTabs = true) const; diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 86680a5..fd51bcf 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -6210,8 +6210,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \list \o qt.nokia.com becomes http://qt.nokia.com \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com - \o localhost becomes http://localhost - \o /home/user/test.html becomes file:///home/user/test.html (if exists) + \o hostname becomes http://hostname + \o /home/user/test.html becomes file:///home/user/test.html \endlist \section2 Tips to avoid erroneous character conversion when dealing with @@ -6228,31 +6228,32 @@ QUrl QUrl::fromUserInput(const QString &userInput) { QString trimmedString = userInput.trimmed(); - // Check the most common case of a valid url with scheme and host first + // Check first for files, since on Windows drive letters can be interpretted as schemes + if (QDir::isAbsolutePath(trimmedString)) + return QUrl::fromLocalFile(trimmedString); + QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); - if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) + QUrl urlPrepended = QUrl::fromEncoded((QLatin1String("http://") + trimmedString).toUtf8(), QUrl::TolerantMode); + + // Check the most common case of a valid url with scheme and host + // We check if the port would be valid by adding the scheme to handle the case host:port + // where the host would be interpretted as the scheme + if (url.isValid() + && !url.scheme().isEmpty() + && (!url.host().isEmpty() || !url.path().isEmpty()) + && urlPrepended.port() == -1) return url; - // Absolute files that exists - if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString)) - return QUrl::fromLocalFile(trimmedString); - - // If the string is missing the scheme or the scheme is not valid prepend a scheme - QString scheme = url.scheme(); - if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) { - // Do not do anything for strings such as "foo", only "foo.com" + // Else, try the prepended one and adjust the scheme from the host name + if (urlPrepended.isValid() && (!urlPrepended.host().isEmpty() || !urlPrepended.path().isEmpty())) + { int dotIndex = trimmedString.indexOf(QLatin1Char('.')); - if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) { - const QString hostscheme = trimmedString.left(dotIndex).toLower(); - QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http"; - trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString; - } - url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + const QString hostscheme = trimmedString.left(dotIndex).toLower(); + if (hostscheme == QLatin1String("ftp")) + urlPrepended.setScheme(QLatin1String("ftp")); + return urlPrepended; } - if (url.isValid()) - return url; - return QUrl(); } // end of BSD code diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index c8fe4e5..03e77aa 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3713,7 +3713,7 @@ void tst_QUrl::fromUserInput_data() QTest::newRow("add scheme-0") << "example.org" << QUrl("http://example.org"); QTest::newRow("add scheme-1") << "www.example.org" << QUrl("http://www.example.org"); QTest::newRow("add scheme-2") << "ftp.example.org" << QUrl("ftp://ftp.example.org"); - QTest::newRow("add scheme-3") << "webkit" << QUrl("webkit"); + QTest::newRow("add scheme-3") << "hostname" << QUrl("http://hostname"); // QUrl's tolerant parser should already handle this QTest::newRow("not-encoded-0") << "http://example.org/test page.html" << QUrl::fromEncoded("http://example.org/test%20page.html"); @@ -3723,6 +3723,9 @@ void tst_QUrl::fromUserInput_data() portUrl.setPort(80); QTest::newRow("port-0") << "example.org:80" << portUrl; QTest::newRow("port-1") << "http://example.org:80" << portUrl; + portUrl.setPath("path"); + QTest::newRow("port-1") << "example.org:80/path" << portUrl; + QTest::newRow("port-1") << "http://example.org:80/path" << portUrl; // mailto doesn't have a ://, but is valid QUrl mailto("ben@example.net"); @@ -3730,10 +3733,11 @@ void tst_QUrl::fromUserInput_data() QTest::newRow("mailto") << "mailto:ben@example.net" << mailto; // misc - QTest::newRow("localhost-0") << "localhost" << QUrl("http://localhost"); QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80"); QTest::newRow("spaces-0") << " http://example.org/test page.html " << QUrl("http://example.org/test%20page.html"); QTest::newRow("trash-0") << "example.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded("http://example.org/test?someData=42%25&someOtherData=abcde#anchor"); + QTest::newRow("other-scheme-0") << "spotify:track:0hO542doVbfGDAGQULMORT" << QUrl("spotify:track:0hO542doVbfGDAGQULMORT"); + QTest::newRow("other-scheme-1") << "weirdscheme:80:otherstuff" << QUrl("weirdscheme:80:otherstuff"); // FYI: The scheme in the resulting url user QUrl authUrl("user:pass@domain.com"); -- cgit v0.12