summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-16 00:30:04 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-16 00:30:04 +0000
commita542e8259fe093c11a55c2656f1fdd3f76c1a1ee (patch)
tree27c37c019533c9125c52da4ab2f58d7ab01202c5 /chrome_frame
parentb917bd60404fb8f76860e6db5db95396166f45d9 (diff)
downloadchromium_src-a542e8259fe093c11a55c2656f1fdd3f76c1a1ee.zip
chromium_src-a542e8259fe093c11a55c2656f1fdd3f76c1a1ee.tar.gz
chromium_src-a542e8259fe093c11a55c2656f1fdd3f76c1a1ee.tar.bz2
Updates for onhttpequiv. Preserving the referrer header, zapping the currently loading document to prevent small documents from executing code.
I'm not enabling httpequiv just yet as there are a couple of things I'm working on related to tests that will break once I make the switch. TEST=There should be no change since the code isn't still active but run all tests just to be safe. BUG=none Review URL: http://codereview.chromium.org/545096 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36436 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/bho.cc86
-rw-r--r--chrome_frame/http_negotiate.cc6
-rw-r--r--chrome_frame/urlmon_url_request.cc8
-rw-r--r--chrome_frame/utils.cc15
-rw-r--r--chrome_frame/utils.h3
5 files changed, 102 insertions, 16 deletions
diff --git a/chrome_frame/bho.cc b/chrome_frame/bho.cc
index 4cb41af..15f1964 100644
--- a/chrome_frame/bho.cc
+++ b/chrome_frame/bho.cc
@@ -146,6 +146,7 @@ STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url,
}
}
}
+
return S_OK;
}
@@ -156,12 +157,56 @@ HRESULT Bho::FinalConstruct() {
void Bho::FinalRelease() {
}
+namespace {
+
+// See comments in Bho::OnHttpEquiv for details.
+void ClearDocumentContents(IUnknown* browser) {
+ ScopedComPtr<IWebBrowser2> web_browser2;
+ if (SUCCEEDED(DoQueryService(SID_SWebBrowserApp, browser,
+ web_browser2.Receive()))) {
+ ScopedComPtr<IDispatch> doc_disp;
+ web_browser2->get_Document(doc_disp.Receive());
+ ScopedComPtr<IHTMLDocument2> doc;
+ if (doc_disp && SUCCEEDED(doc.QueryFrom(doc_disp))) {
+ SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 0);
+ doc->write(sa);
+ ::SafeArrayDestroy(sa);
+ }
+ }
+}
+
+// Returns true if the currently loaded document in the browser has
+// any embedded items such as a frame or an iframe.
+bool DocumentHasEmbeddedItems(IUnknown* browser) {
+ bool has_embedded_items = false;
+
+ ScopedComPtr<IWebBrowser2> web_browser2;
+ ScopedComPtr<IDispatch> document;
+ if (SUCCEEDED(DoQueryService(SID_SWebBrowserApp, browser,
+ web_browser2.Receive())) &&
+ SUCCEEDED(web_browser2->get_Document(document.Receive()))) {
+ ScopedComPtr<IOleContainer> container;
+ if (SUCCEEDED(container.QueryFrom(document))) {
+ ScopedComPtr<IEnumUnknown> enumerator;
+ container->EnumObjects(OLECONTF_EMBEDDINGS, enumerator.Receive());
+ if (enumerator) {
+ ScopedComPtr<IUnknown> unk;
+ DWORD fetched = 0;
+ enumerator->Next(1, unk.Receive(), &fetched);
+ has_embedded_items = (fetched != 0);
+ }
+ }
+ }
+
+ return has_embedded_items;
+}
+
+} // end namespace
+
HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
IBrowserService* browser, IShellView* shell_view, BOOL done,
VARIANT* in_arg, VARIANT* out_arg) {
- // OnHttpEquiv is invoked for meta tags within sub frames as well.
- // We want to switch renderers only for the top level frame.
- bool is_top_level = (browser->GetBrowserIndex() == -1);
+ DLOG(INFO) << __FUNCTION__ << " done:" << done;
// OnHttpEquiv with 'done' set to TRUE is called for all pages.
// 0 or more calls with done set to FALSE are made.
@@ -171,6 +216,16 @@ HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
if (done) {
if (CheckForCFNavigation(browser, false)) {
+ // TODO(tommi): See if we can't figure out a cleaner way to avoid this.
+ // For small documents we can hit a problem here. When we attempt to
+ // navigate the document again in CF, mshtml can "complete" the current
+ // navigation (if all data is available) and fire off script events such
+ // as onload and even render the page. This will happen inside
+ // NavigateBrowserToMoniker below.
+ // To work around this, we clear the contents of the document before
+ // opening it up in CF.
+ ClearDocumentContents(browser);
+
ScopedComPtr<IOleObject> mshtml_ole_object;
HRESULT hr = shell_view->GetItemObject(SVGIO_BACKGROUND, IID_IOleObject,
reinterpret_cast<void**>(mshtml_ole_object.Receive()));
@@ -186,8 +241,19 @@ HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
// This bind context will be discarded by IE and a new one
// constructed, so it's OK to create a sync bind context.
::CreateBindCtx(0, bind_context.Receive());
+
DCHECK(bind_context);
- hr = NavigateBrowserToMoniker(browser, moniker, bind_context);
+
+ // If there's a referrer, preserve it.
+ std::wstring headers;
+ Bho* chrome_frame_bho = Bho::GetCurrentThreadBhoInstance();
+ if (chrome_frame_bho && !chrome_frame_bho->referrer().empty()) {
+ headers = StringPrintf(L"Referer: %ls\r\n\r\n",
+ ASCIIToWide(chrome_frame_bho->referrer()).c_str());
+ }
+
+ hr = NavigateBrowserToMoniker(browser, moniker, headers.c_str(),
+ bind_context);
} else {
DLOG(ERROR) << "Couldn't get the current moniker";
}
@@ -202,9 +268,17 @@ HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
// HttpNegotiatePatch::ReportProgress when the mime type is reported.
}
}
- } else if (is_top_level && in_arg && VT_BSTR == V_VT(in_arg)) {
+ } else if (in_arg && VT_BSTR == V_VT(in_arg)) {
if (StrStrI(V_BSTR(in_arg), kChromeContentPrefix)) {
- MarkBrowserOnThreadForCFNavigation(browser);
+ // OnHttpEquiv is invoked for meta tags within sub frames as well.
+ // We want to switch renderers only for the top level frame.
+ // The theory here is that if there are any existing embedded items
+ // (frames or iframes) in the current document, then the http-equiv
+ // notification is coming from those and not the top level document.
+ // The embedded items should only be created once the top level
+ // doc has been created.
+ if (!DocumentHasEmbeddedItems(browser))
+ MarkBrowserOnThreadForCFNavigation(browser);
}
}
diff --git a/chrome_frame/http_negotiate.cc b/chrome_frame/http_negotiate.cc
index b938cae..f118baf 100644
--- a/chrome_frame/http_negotiate.cc
+++ b/chrome_frame/http_negotiate.cc
@@ -131,7 +131,7 @@ HRESULT HttpNegotiatePatch::PatchHttpNegotiate(IUnknown* to_patch) {
HRESULT HttpNegotiatePatch::BeginningTransaction(
IHttpNegotiate_BeginningTransaction_Fn original, IHttpNegotiate* me,
LPCWSTR url, LPCWSTR headers, DWORD reserved, LPWSTR* additional_headers) {
- DLOG(INFO) << __FUNCTION__ << " " << url;
+ DLOG(INFO) << __FUNCTION__ << " " << url << " headers:\n" << headers;
HRESULT hr = original(me, url, headers, reserved, additional_headers);
@@ -145,8 +145,10 @@ HRESULT HttpNegotiatePatch::BeginningTransaction(
using net::HttpUtil;
std::string ascii_headers;
- if (*additional_headers)
+ if (*additional_headers) {
ascii_headers = WideToASCII(*additional_headers);
+ DLOG(INFO) << __FUNCTION__ << " additional headers: " << ascii_headers;
+ }
HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(),
ascii_headers.end(), "\r\n");
diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc
index 8831447..5a946ce 100644
--- a/chrome_frame/urlmon_url_request.cc
+++ b/chrome_frame/urlmon_url_request.cc
@@ -150,7 +150,8 @@ class WrappedBindContext : public IBindCtx,
}
STDMETHOD(RegisterObjectParam)(LPOLESTR key, IUnknown* object) {
- DLOG(INFO) << "In " << __FUNCTION__ << " for object: " << this;
+ DLOG(INFO) << "In " << __FUNCTION__ << " for object: " << this << " key: "
+ << key;
ScopedComPtr<IBindCtx> bind_context;
HRESULT hr = GetMarshalledBindContext(bind_context.Receive());
@@ -161,7 +162,8 @@ class WrappedBindContext : public IBindCtx,
}
STDMETHOD(GetObjectParam)(LPOLESTR key, IUnknown** object) {
- DLOG(INFO) << "In " << __FUNCTION__ << " for object: " << this;
+ DLOG(INFO) << "In " << __FUNCTION__ << " for object: " << this << " key: "
+ << key;
ScopedComPtr<IBindCtx> bind_context;
HRESULT hr = GetMarshalledBindContext(bind_context.Receive());
@@ -339,7 +341,7 @@ void UrlmonUrlRequest::TransferToHost(IUnknown* host) {
ScopedComPtr<IBindCtx> bind_context;
CreateBindCtx(0, bind_context.Receive());
DCHECK(bind_context);
- NavigateBrowserToMoniker(host, moniker_, bind_context);
+ NavigateBrowserToMoniker(host, moniker_, NULL, bind_context);
moniker_.Release();
}
}
diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc
index af85cb4..67b1217 100644
--- a/chrome_frame/utils.cc
+++ b/chrome_frame/utils.cc
@@ -636,7 +636,7 @@ bool IsOptInUrl(const wchar_t* url) {
}
HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
- IBindCtx* bind_ctx) {
+ const wchar_t* headers, IBindCtx* bind_ctx) {
DCHECK(browser);
DCHECK(moniker);
DCHECK(bind_ctx);
@@ -667,6 +667,10 @@ HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
ScopedComPtr<IUriContainer> uri_container;
hr = uri_container.QueryFrom(moniker);
+ ScopedVariant headers_var;
+ if (headers && headers[0])
+ headers_var.Set(headers);
+
if (uri_container) {
// IE7 and IE8.
const IID* interface_ids[] = {
@@ -688,8 +692,10 @@ HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
ScopedComPtr<IUri> uri_obj;
uri_container->GetIUri(uri_obj.Receive());
DCHECK(uri_obj);
- hr = browser_priv2->NavigateWithBindCtx2(uri_obj, NULL, NULL, NULL, NULL,
- bind_ctx, NULL);
+
+ hr = browser_priv2->NavigateWithBindCtx2(uri_obj, NULL, NULL, NULL,
+ headers_var.AsInput(), bind_ctx,
+ NULL);
DLOG_IF(WARNING, FAILED(hr))
<< StringPrintf(L"NavigateWithBindCtx2 0x%08X", hr);
}
@@ -702,7 +708,8 @@ HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
if (SUCCEEDED(hr = browser_priv.QueryFrom(web_browser2))) {
ScopedVariant var_url(url);
hr = browser_priv->NavigateWithBindCtx(var_url.AsInput(), NULL, NULL,
- NULL, NULL, bind_ctx, NULL);
+ NULL, headers_var.AsInput(),
+ bind_ctx, NULL);
DLOG_IF(WARNING, FAILED(hr))
<< StringPrintf(L"NavigateWithBindCtx 0x%08X", hr);
} else {
diff --git a/chrome_frame/utils.h b/chrome_frame/utils.h
index ab25cf2..8048beb 100644
--- a/chrome_frame/utils.h
+++ b/chrome_frame/utils.h
@@ -223,8 +223,9 @@ HRESULT GetUrlFromMoniker(IMoniker* moniker, IBindCtx* bind_context,
std::wstring* url);
// Navigates an IWebBrowser2 object to a moniker.
+// |headers| can be NULL.
HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
- IBindCtx* bind_ctx);
+ const wchar_t* headers, IBindCtx* bind_ctx);
// Raises a flag on the current thread (using TLS) to indicate that an
// in-progress navigation should be rendered in chrome frame.