summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome_frame/bho.cc2
-rw-r--r--chrome_frame/chrome_active_document.cc32
-rw-r--r--chrome_frame/chrome_frame_activex_base.h11
-rw-r--r--chrome_frame/test/navigation_test.cc77
-rw-r--r--chrome_frame/urlmon_moniker.h30
5 files changed, 143 insertions, 9 deletions
diff --git a/chrome_frame/bho.cc b/chrome_frame/bho.cc
index 5e74881..35623b3 100644
--- a/chrome_frame/bho.cc
+++ b/chrome_frame/bho.cc
@@ -132,6 +132,8 @@ STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url,
if (is_top_level) {
set_url(url->bstrVal);
set_referrer("");
+ set_post_data(post_data);
+ set_headers(headers);
}
return S_OK;
}
diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc
index 6000505..deee511 100644
--- a/chrome_frame/chrome_active_document.cc
+++ b/chrome_frame/chrome_active_document.cc
@@ -74,6 +74,7 @@ HRESULT ChromeActiveDocument::FinalConstruct() {
// optimization to get Chrome active documents to load faster.
ChromeActiveDocument* cached_document = g_active_doc_cache.Get();
if (cached_document && cached_document->IsValid()) {
+ SetResourceModule();
DCHECK(automation_client_.get() == NULL);
automation_client_.swap(cached_document->automation_client_);
DVLOG(1) << "Reusing automation client instance from " << cached_document;
@@ -1070,6 +1071,37 @@ HRESULT ChromeActiveDocument::OnRefreshPage(const GUID* cmd_group_guid,
0x80000000 | OLECMDIDF_WINDOWSTATE_USERVISIBLE_VALID, NULL, NULL);
}
+ NavigationManager* mgr = NavigationManager::GetThreadInstance();
+ DLOG_IF(ERROR, !mgr) << "Couldn't get instance of NavigationManager";
+
+ // If ChromeFrame was activated on this page as a result of a document
+ // received in response to a top level post, then we ask the user for
+ // permission to repost and issue a navigation with the saved post data
+ // which reinitates the whole sequence, i.e. the server receives the top
+ // level post and chrome frame will be reactivated in response.
+ if (mgr && mgr->post_data().type() != VT_EMPTY) {
+ if (MessageBox(
+ SimpleResourceLoader::Get(IDS_HTTP_POST_WARNING).c_str(),
+ SimpleResourceLoader::Get(IDS_HTTP_POST_WARNING_TITLE).c_str(),
+ MB_YESNO | MB_ICONEXCLAMATION) == IDYES) {
+ base::win::ScopedComPtr<IWebBrowser2> web_browser2;
+ DoQueryService(SID_SWebBrowserApp, m_spClientSite,
+ web_browser2.Receive());
+ DCHECK(web_browser2);
+ VARIANT empty = base::win::ScopedVariant::kEmptyVariant;
+ VARIANT flags = { VT_I4 };
+ V_I4(&flags) = navNoHistory;
+
+ return web_browser2->Navigate2(base::win::ScopedVariant(url_).AsInput(),
+ &flags,
+ &empty,
+ const_cast<VARIANT*>(&mgr->post_data()),
+ const_cast<VARIANT*>(&mgr->headers()));
+ } else {
+ return S_OK;
+ }
+ }
+
TabProxy* tab_proxy = GetTabProxy();
if (tab_proxy) {
tab_proxy->ReloadAsync();
diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h
index 1dd2755..c7dd5cf 100644
--- a/chrome_frame/chrome_frame_activex_base.h
+++ b/chrome_frame/chrome_frame_activex_base.h
@@ -251,17 +251,12 @@ END_MSG_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
- virtual void SetResourceModule() {
+ void SetResourceModule() {
DCHECK(NULL == prev_resource_instance_);
SimpleResourceLoader* loader_instance = SimpleResourceLoader::instance();
DCHECK(loader_instance);
HMODULE res_dll = loader_instance->GetResourceModuleHandle();
- prev_resource_instance_ = _AtlBaseModule.SetResourceInstance(res_dll);
- }
-
- virtual void ClearResourceModule() {
- _AtlBaseModule.SetResourceInstance(prev_resource_instance_);
- prev_resource_instance_ = NULL;
+ _AtlBaseModule.SetResourceInstance(res_dll);
}
HRESULT FinalConstruct() {
@@ -286,8 +281,6 @@ END_MSG_MAP()
void FinalRelease() {
Uninitialize();
-
- ClearResourceModule();
}
void ResetUrlRequestManager() {
diff --git a/chrome_frame/test/navigation_test.cc b/chrome_frame/test/navigation_test.cc
index 0918037..457793d 100644
--- a/chrome_frame/test/navigation_test.cc
+++ b/chrome_frame/test/navigation_test.cc
@@ -1026,5 +1026,82 @@ TEST_F(FullTabSeleniumTest, Core) {
LaunchIENavigateAndLoop(url, kSeleniumTestTimeout);
}
+// See bug http://code.google.com/p/chromium/issues/detail?id=64901
+// This test does the following:-
+// Navigates IE to a non ChromeFrame URL.
+// Performs a top level form post in the document
+// In response to the POST send over a html document containing a meta tag
+// This would cause IE to switch to ChromeFrame.
+// Refresh the page in ChromeFrame.
+// This should bring up a confirmation dialog which we hit yes on. This should
+// reissue the top level post request in response to which the html content
+// containing the meta tag is sent again.
+TEST_F(FullTabDownloadTest, TopLevelPostReissueFromChromeFramePage) {
+ chrome_frame_test::MockWindowObserver post_reissue_watcher;
+ post_reissue_watcher.WatchWindow("Confirm Form Resubmission", "");
+
+ EXPECT_CALL(server_mock_, Get(_, StrEq(L"/post_source.html"), _))
+ .WillOnce(SendFast(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html\r\n",
+ "<html>"
+ "<head>"
+ " <script type=\"text/javascript\">"
+ " function onLoad() {"
+ " document.getElementById(\"myform\").submit();}</script></head>"
+ " <body onload=\"setTimeout(onLoad, 2000);\">"
+ " <form id=\"myform\" action=\"post_target.html\" method=\"POST\">"
+ "</form></body></html>"));
+
+ EXPECT_CALL(server_mock_, Post(_, StrEq(L"/post_target.html"), _))
+ .Times(2)
+ .WillRepeatedly(
+ SendFast(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html\r\n",
+ "<html>"
+ "<head><meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />"
+ "</head>"
+ "<body> Target page in ChromeFrame </body>"
+ "</html>"));
+
+ EXPECT_CALL(post_reissue_watcher, OnWindowOpen(_))
+ .WillOnce(DelayAccDoDefaultAction(
+ AccObjectMatcher(L"Yes", L"push button"),
+ 1000));
+
+ EXPECT_CALL(post_reissue_watcher, OnWindowClose(_));
+
+ std::wstring src_url = server_mock_.Resolve(L"/post_source.html");
+ std::wstring tgt_url = server_mock_.Resolve(L"/post_target.html");
+
+ EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber());
+
+ EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_,
+ testing::Field(&VARIANT::bstrVal,
+ StrEq(src_url)), _, _, _, _, _));
+ EXPECT_CALL(ie_mock_, OnNavigateComplete2(_,
+ testing::Field(&VARIANT::bstrVal,
+ StrEq(src_url))));
+ EXPECT_CALL(ie_mock_, OnLoad(false, StrEq(src_url)));
+
+ EXPECT_CALL(ie_mock_, OnLoad(true, StrEq(tgt_url)))
+ .Times(2);
+
+ EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_,
+ testing::Field(&VARIANT::bstrVal,
+ StrEq(tgt_url)), _, _, _, _, _))
+ .Times(2);
+
+ EXPECT_CALL(ie_mock_, OnNavigateComplete2(_,
+ testing::Field(&VARIANT::bstrVal,
+ StrEq(tgt_url))))
+ .Times(2)
+ .WillOnce(testing::DoAll(DelayRefresh(&ie_mock_, &loop_, 2000),
+ DelayCloseBrowserMock(&loop_, 4000, &ie_mock_)))
+ .WillOnce(testing::Return());
+
+ LaunchIENavigateAndLoop(src_url, kChromeFrameLongNavigationTimeoutInSeconds);
+}
} // namespace chrome_frame_test
diff --git a/chrome_frame/urlmon_moniker.h b/chrome_frame/urlmon_moniker.h
index a5b7fdf..dde70adb 100644
--- a/chrome_frame/urlmon_moniker.h
+++ b/chrome_frame/urlmon_moniker.h
@@ -13,6 +13,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/thread_local.h"
+#include "base/win/scoped_variant.h"
#include "googleurl/src/gurl.h"
#include "chrome_frame/utils.h"
@@ -122,9 +123,38 @@ class NavigationManager {
// and need to switch over from mshtml to CF.
virtual HRESULT NavigateToCurrentUrlInCF(IBrowserService* browser);
+ void set_post_data(VARIANT* post_data) {
+ post_data_.Reset();
+ if (post_data) {
+ if (V_VT(post_data) == (VT_BYREF | VT_VARIANT)) {
+ post_data_.Set(*post_data->pvarVal);
+ } else {
+ NOTREACHED() << "unexpected type for post_data: "
+ << std::hex << post_data->vt;
+ }
+ }
+ }
+
+ const base::win::ScopedVariant& post_data() const {
+ return post_data_;
+ }
+
+ void set_headers(VARIANT* headers) {
+ headers_.Reset();
+ if (headers) {
+ headers_ = *headers;
+ }
+ }
+
+ const base::win::ScopedVariant& headers() const {
+ return headers_;
+ }
+
protected:
std::string referrer_;
std::wstring url_;
+ base::win::ScopedVariant post_data_;
+ base::win::ScopedVariant headers_;
static base::LazyInstance<base::ThreadLocalPointer<NavigationManager> >
thread_singleton_;