Fix status code and headers for iframes
QWebFrame::url() does not return a valid URL for iframes. We can't just look up the requested URL in m_responses because the request may have been redirected, so instead we keep track of redirects and set up the NetworkResponse when the final reply is received.
This commit is contained in:
parent
e80a9c8b92
commit
5127c01366
|
@ -9,15 +9,29 @@ describe Capybara::Webkit::Driver do
|
|||
let(:driver) do
|
||||
driver_for_app do
|
||||
get "/" do
|
||||
if in_iframe_request?
|
||||
p_id = "farewell"
|
||||
msg = "goodbye"
|
||||
iframe = nil
|
||||
if params[:iframe] == "true"
|
||||
redirect '/iframe'
|
||||
else
|
||||
p_id = "greeting"
|
||||
msg = "hello"
|
||||
iframe = "<iframe id=\"f\" src=\"/?iframe=true\"></iframe>"
|
||||
<<-HTML
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
#display_none { display: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="f" src="/?iframe=true"></iframe>
|
||||
<script type="text/javascript">
|
||||
document.write("<p id='greeting'>hello</p>");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
end
|
||||
end
|
||||
|
||||
get '/iframe' do
|
||||
headers 'X-Redirected' => 'true'
|
||||
<<-HTML
|
||||
<html>
|
||||
<head>
|
||||
|
@ -26,18 +40,13 @@ describe Capybara::Webkit::Driver do
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
#{iframe}
|
||||
<script type="text/javascript">
|
||||
document.write("<p id='#{p_id}'>#{msg}</p>");
|
||||
document.write("<p id='farewell'>goodbye</p>");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
end
|
||||
|
||||
def in_iframe_request?
|
||||
params[:iframe] == "true"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -90,13 +99,7 @@ describe Capybara::Webkit::Driver do
|
|||
|
||||
it "returns the current URL" do
|
||||
driver.within_frame("f") do
|
||||
driver.current_url.should == driver_url(driver, "/?iframe=true")
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the source code for the page" do
|
||||
driver.within_frame("f") do
|
||||
driver.source.should =~ %r{<html>.*farewell.*}m
|
||||
driver.current_url.should == driver_url(driver, "/iframe")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -121,6 +124,18 @@ describe Capybara::Webkit::Driver do
|
|||
|
||||
driver.current_url.should == original_url
|
||||
end
|
||||
|
||||
it "returns the headers for the page" do
|
||||
driver.within_frame("f") do
|
||||
driver.response_headers['X-Redirected'].should == "true"
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the status code for the page" do
|
||||
driver.within_frame("f") do
|
||||
driver.status_code.should == 200
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "error iframe app" do
|
||||
|
@ -150,8 +165,10 @@ describe Capybara::Webkit::Driver do
|
|||
context "redirect app" do
|
||||
let(:driver) do
|
||||
driver_for_app do
|
||||
enable :sessions
|
||||
|
||||
get '/target' do
|
||||
headers 'X-Redirected' => 'true'
|
||||
headers 'X-Redirected' => (session.delete(:redirected) || false).to_s
|
||||
"<p>#{env['CONTENT_TYPE']}</p>"
|
||||
end
|
||||
|
||||
|
@ -172,7 +189,12 @@ describe Capybara::Webkit::Driver do
|
|||
end
|
||||
|
||||
get '/redirect-me' do
|
||||
redirect '/target'
|
||||
if session[:redirected]
|
||||
redirect '/target'
|
||||
else
|
||||
session[:redirected] = true
|
||||
redirect '/redirect-me'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -200,13 +222,16 @@ describe Capybara::Webkit::Driver do
|
|||
it "should make headers available through response_headers" do
|
||||
driver.visit('/redirect-me')
|
||||
driver.response_headers['X-Redirected'].should == "true"
|
||||
driver.visit('/target')
|
||||
driver.response_headers['X-Redirected'].should == "false"
|
||||
end
|
||||
|
||||
it "should make the status code available through status_code" do
|
||||
driver.visit('/redirect-me')
|
||||
driver.status_code.should == 200
|
||||
driver.visit('/target')
|
||||
driver.status_code.should == 200
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "css app" do
|
||||
|
|
|
@ -9,7 +9,7 @@ void Authenticate::start() {
|
|||
QString username = arguments()[0];
|
||||
QString password = arguments()[1];
|
||||
|
||||
NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
|
||||
NetworkAccessManager* networkAccessManager = page()->networkAccessManager();
|
||||
networkAccessManager->setUserName(username);
|
||||
networkAccessManager->setPassword(password);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ Header::Header(WebPageManager *manager, QStringList &arguments, QObject *parent)
|
|||
void Header::start() {
|
||||
QString key = arguments()[0];
|
||||
QString value = arguments()[1];
|
||||
NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
|
||||
NetworkAccessManager* networkAccessManager = page()->networkAccessManager();
|
||||
if (key.toLower().replace("-", "_") == "user_agent") {
|
||||
page()->setUserAgent(value);
|
||||
} else {
|
||||
|
|
|
@ -30,10 +30,18 @@ QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operat
|
|||
};
|
||||
|
||||
void NetworkAccessManager::finished(QNetworkReply *reply) {
|
||||
NetworkResponse response;
|
||||
response.statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
response.headers = reply->rawHeaderPairs();
|
||||
m_responses[reply->url()] = response;
|
||||
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||
if (redirectUrl.isValid())
|
||||
m_redirectMappings[reply->url().resolved(redirectUrl)] = reply->url();
|
||||
else {
|
||||
QUrl requestedUrl = reply->url();
|
||||
while (m_redirectMappings.contains(requestedUrl))
|
||||
requestedUrl = m_redirectMappings.take(requestedUrl);
|
||||
NetworkResponse response;
|
||||
response.statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
response.headers = reply->rawHeaderPairs();
|
||||
m_responses[requestedUrl] = response;
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkAccessManager::addHeader(QString key, QString value) {
|
||||
|
|
|
@ -35,6 +35,7 @@ class NetworkAccessManager : public QNetworkAccessManager {
|
|||
QHash<QUrl, NetworkResponse> m_responses;
|
||||
bool isBlacklisted(QUrl url);
|
||||
QNetworkReply* noOpRequest();
|
||||
QHash<QUrl, QUrl> m_redirectMappings;
|
||||
|
||||
private slots:
|
||||
void provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "SetProxy.h"
|
||||
#include "WebPage.h"
|
||||
#include "WebPageManager.h"
|
||||
#include <QNetworkAccessManager>
|
||||
#include "NetworkAccessManager.h"
|
||||
#include <QNetworkProxy>
|
||||
|
||||
SetProxy::SetProxy(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
|
||||
|
|
|
@ -8,7 +8,7 @@ SetUrlBlacklist::SetUrlBlacklist(WebPageManager *manager, QStringList &arguments
|
|||
}
|
||||
|
||||
void SetUrlBlacklist::start() {
|
||||
NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
|
||||
NetworkAccessManager* networkAccessManager = page()->networkAccessManager();
|
||||
networkAccessManager->setUrlBlacklist(arguments());
|
||||
emit finished(new Response(true));
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#include "Source.h"
|
||||
#include "WebPage.h"
|
||||
#include "WebPageManager.h"
|
||||
#include "NetworkAccessManager.h"
|
||||
|
||||
Source::Source(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
||||
}
|
||||
|
||||
void Source::start() {
|
||||
QNetworkAccessManager* accessManager = page()->networkAccessManager();
|
||||
NetworkAccessManager* accessManager = page()->networkAccessManager();
|
||||
QNetworkRequest request(page()->currentFrame()->requestedUrl());
|
||||
reply = accessManager->get(request);
|
||||
|
||||
|
|
|
@ -253,11 +253,15 @@ void WebPage::setSkipImageLoading(bool skip) {
|
|||
}
|
||||
|
||||
int WebPage::getLastStatus() {
|
||||
return qobject_cast<NetworkAccessManager *>(networkAccessManager())->statusFor(currentFrame()->url());
|
||||
return networkAccessManager()->statusFor(currentFrame()->requestedUrl());
|
||||
}
|
||||
|
||||
const QList<QNetworkReply::RawHeaderPair> &WebPage::pageHeaders() {
|
||||
return qobject_cast<NetworkAccessManager *>(networkAccessManager())->headersFor(currentFrame()->url());
|
||||
return networkAccessManager()->headersFor(currentFrame()->requestedUrl());
|
||||
}
|
||||
|
||||
NetworkAccessManager *WebPage::networkAccessManager() {
|
||||
return qobject_cast<NetworkAccessManager *>(QWebPage::networkAccessManager());
|
||||
}
|
||||
|
||||
void WebPage::handleUnsupportedContent(QNetworkReply *reply) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <QtWebKit>
|
||||
|
||||
class WebPageManager;
|
||||
class NetworkAccessManager;
|
||||
|
||||
class WebPage : public QWebPage {
|
||||
Q_OBJECT
|
||||
|
@ -32,6 +33,7 @@ class WebPage : public QWebPage {
|
|||
QString getWindowName();
|
||||
bool matchesWindowSelector(QString);
|
||||
void setFocus();
|
||||
NetworkAccessManager *networkAccessManager();
|
||||
|
||||
public slots:
|
||||
bool shouldInterruptJavaScript();
|
||||
|
|
Loading…
Reference in New Issue