From 353fe860b2faf7f29a89ccdb2ee3813c2052e6a6 Mon Sep 17 00:00:00 2001 From: Matthew Mongeau Date: Thu, 15 Sep 2011 11:22:10 -0400 Subject: [PATCH] Handle unsupported content types gracefully --- spec/driver_spec.rb | 14 ++++++++++++++ src/Connection.cpp | 3 ++- src/UnsupportedContentHandler.cpp | 23 +++++++++++++++++++++++ src/UnsupportedContentHandler.h | 16 ++++++++++++++++ src/Visit.cpp | 2 +- src/WebPage.cpp | 11 ++++++++++- src/WebPage.h | 4 ++++ src/webkit_server.pro | 4 ++-- 8 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 src/UnsupportedContentHandler.cpp create mode 100644 src/UnsupportedContentHandler.h diff --git a/spec/driver_spec.rb b/spec/driver_spec.rb index 8d645a99..20f4e4a8 100644 --- a/spec/driver_spec.rb +++ b/spec/driver_spec.rb @@ -134,6 +134,20 @@ end end + context "css app" do + before(:all) do + body = "css" + @app = lambda do |env| + [200, {"Content-Type" => "text/css", "Content-Length" => body.length.to_s}, [body]] + end + end + + it "should render unsupported content types gracefully" do + subject.visit("/") + subject.body.should =~ /css/ + end + end + context "hello app" do before(:all) do @app = lambda do |env| diff --git a/src/Connection.cpp b/src/Connection.cpp index 1da9a0ed..a79cd540 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -1,5 +1,6 @@ #include "Connection.h" #include "WebPage.h" +#include "UnsupportedContentHandler.h" #include "Visit.h" #include "Find.h" #include "Command.h" @@ -28,7 +29,7 @@ Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) : m_pageSuccess = true; m_commandWaiting = false; connect(m_socket, SIGNAL(readyRead()), this, SLOT(checkNext())); - connect(m_page, SIGNAL(loadFinished(bool)), this, SLOT(pendingLoadFinished(bool))); + connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool))); } void Connection::checkNext() { diff --git a/src/UnsupportedContentHandler.cpp b/src/UnsupportedContentHandler.cpp new file mode 100644 index 00000000..7c3ce875 --- /dev/null +++ b/src/UnsupportedContentHandler.cpp @@ -0,0 +1,23 @@ +#include "UnsupportedContentHandler.h" +#include "WebPage.h" +#include + +UnsupportedContentHandler::UnsupportedContentHandler(WebPage *page, QNetworkReply *reply, QObject *parent) : QObject(parent) { + m_page = page; + m_reply = reply; + connect(m_reply, SIGNAL(finished()), this, SLOT(handleUnsupportedContent())); + disconnect(m_page, SIGNAL(loadFinished(bool)), m_page, SLOT(loadFinished(bool))); +} + +void UnsupportedContentHandler::handleUnsupportedContent() { + QVariant contentMimeType = m_reply->header(QNetworkRequest::ContentTypeHeader); + if(!contentMimeType.isNull()) { + QByteArray text = m_reply->readAll(); + m_page->mainFrame()->setContent(text, QString("text/plain"), m_reply->url()); + connect(m_page, SIGNAL(loadFinished(bool)), m_page, SLOT(loadFinished(bool))); + m_page->loadFinished(true); + } else { + connect(m_page, SIGNAL(loadFinished(bool)), m_page, SLOT(loadFinished(bool))); + m_page->loadFinished(false); + } +} diff --git a/src/UnsupportedContentHandler.h b/src/UnsupportedContentHandler.h new file mode 100644 index 00000000..c2cbddda --- /dev/null +++ b/src/UnsupportedContentHandler.h @@ -0,0 +1,16 @@ +#include +class WebPage; +class QNetworkReply; +class UnsupportedContentHandler : public QObject { + Q_OBJECT + + public: + UnsupportedContentHandler(WebPage *page, QNetworkReply *reply, QObject *parent = 0); + + public slots: + void handleUnsupportedContent(); + + private: + WebPage *m_page; + QNetworkReply *m_reply; +}; diff --git a/src/Visit.cpp b/src/Visit.cpp index 7592a846..b2340479 100644 --- a/src/Visit.cpp +++ b/src/Visit.cpp @@ -3,7 +3,7 @@ #include "WebPage.h" Visit::Visit(WebPage *page, QObject *parent) : Command(page, parent) { - connect(page, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); + connect(page, SIGNAL(pageFinished(bool)), this, SLOT(loadFinished(bool))); } void Visit::start(QStringList &arguments) { diff --git a/src/WebPage.cpp b/src/WebPage.cpp index ecd80b8f..753ed115 100644 --- a/src/WebPage.cpp +++ b/src/WebPage.cpp @@ -1,10 +1,12 @@ #include "WebPage.h" #include "JavascriptInvocation.h" #include "NetworkAccessManager.h" +#include "UnsupportedContentHandler.h" #include #include WebPage::WebPage(QObject *parent) : QWebPage(parent) { + setForwardUnsupportedContent(true); loadJavascript(); setUserStylesheet(); @@ -15,6 +17,8 @@ WebPage::WebPage(QObject *parent) : QWebPage(parent) { connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); connect(this, SIGNAL(frameCreated(QWebFrame *)), this, SLOT(frameCreated(QWebFrame *))); + connect(this, SIGNAL(unsupportedContent(QNetworkReply*)), + this, SLOT(handleUnsupportedContent(QNetworkReply*))); } void WebPage::setCustomNetworkAccessManager() { @@ -111,8 +115,8 @@ void WebPage::loadStarted() { } void WebPage::loadFinished(bool success) { - Q_UNUSED(success); m_loading = false; + emit pageFinished(success); } bool WebPage::isLoading() const { @@ -198,3 +202,8 @@ void WebPage::resetResponseHeaders() { QString WebPage::pageHeaders() { return m_pageHeaders; } + +void WebPage::handleUnsupportedContent(QNetworkReply *reply) { + UnsupportedContentHandler *handler = new UnsupportedContentHandler(this, reply); + Q_UNUSED(handler); +} diff --git a/src/WebPage.h b/src/WebPage.h index 32f73f2f..daef8fcc 100644 --- a/src/WebPage.h +++ b/src/WebPage.h @@ -25,6 +25,10 @@ class WebPage : public QWebPage { QString pageHeaders(); void frameCreated(QWebFrame *); void replyFinished(QNetworkReply *reply); + void handleUnsupportedContent(QNetworkReply *reply); + + signals: + void pageFinished(bool); protected: virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID); diff --git a/src/webkit_server.pro b/src/webkit_server.pro index eb2df76b..4418dc6e 100644 --- a/src/webkit_server.pro +++ b/src/webkit_server.pro @@ -1,8 +1,8 @@ TEMPLATE = app TARGET = webkit_server DESTDIR = . -HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h Response.h NetworkAccessManager.h Header.h Render.h body.h Status.h Headers.h -SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp Response.cpp NetworkAccessManager.cpp Header.cpp Render.cpp body.cpp Status.cpp Headers.cpp +HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h Response.h NetworkAccessManager.h Header.h Render.h body.h Status.h Headers.h UnsupportedContentHandler.h +SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp Response.cpp NetworkAccessManager.cpp Header.cpp Render.cpp body.cpp Status.cpp Headers.cpp UnsupportedContentHandler.cpp RESOURCES = webkit_server.qrc QT += network webkit CONFIG += console