Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4932)

Unified Diff: chrome_frame/protocol_sink_wrap.cc

Issue 3051018: Ensure that window.open requests issued by ChromeFrame carry the correct cook... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome_frame/protocol_sink_wrap.h ('k') | chrome_frame/test/util_unittests.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome_frame/protocol_sink_wrap.cc
===================================================================
--- chrome_frame/protocol_sink_wrap.cc (revision 53833)
+++ chrome_frame/protocol_sink_wrap.cc (working copy)
@@ -13,6 +13,7 @@
#include "base/singleton.h"
#include "base/string_util.h"
+#include "chrome_frame/bho.h"
#include "chrome_frame/bind_context_info.h"
#include "chrome_frame/function_stub.h"
#include "chrome_frame/utils.h"
@@ -30,6 +31,8 @@
static const int kInternetProtocolStartIndex = 3;
static const int kInternetProtocolReadIndex = 9;
static const int kInternetProtocolStartExIndex = 13;
+static const int kInternetProtocolLockRequestIndex = 11;
+static const int kInternetProtocolUnlockRequestIndex = 12;
// IInternetProtocol/Ex patches.
@@ -55,10 +58,18 @@
ULONG size,
ULONG* size_read);
+STDMETHODIMP Hook_LockRequest(InternetProtocol_LockRequest_Fn orig_req,
+ IInternetProtocol* protocol, DWORD dwOptions);
+
+STDMETHODIMP Hook_UnlockRequest(InternetProtocol_UnlockRequest_Fn orig_req,
+ IInternetProtocol* protocol);
+
/////////////////////////////////////////////////////////////////////////////
BEGIN_VTABLE_PATCHES(CTransaction)
VTABLE_PATCH_ENTRY(kInternetProtocolStartIndex, Hook_Start)
VTABLE_PATCH_ENTRY(kInternetProtocolReadIndex, Hook_Read)
+ VTABLE_PATCH_ENTRY(kInternetProtocolLockRequestIndex, Hook_LockRequest)
+ VTABLE_PATCH_ENTRY(kInternetProtocolUnlockRequestIndex, Hook_UnlockRequest)
END_VTABLE_PATCHES()
BEGIN_VTABLE_PATCHES(CTransaction2)
@@ -502,7 +513,6 @@
DCHECK_EQ(CHROME, renderer_type_);
ScopedComPtr<IWinInetHttpInfo> info;
info.QueryFrom(delegate);
- DCHECK(info);
if (info) {
char buffer[4096] = {0};
DWORD len = sizeof(buffer);
@@ -512,6 +522,8 @@
buffer, &len, &flags, 0);
if (hr == S_OK && len > 0)
referrer_.assign(buffer);
+ } else {
+ DLOG(WARNING) << "Failed to QI for IWinInetHttpInfo";
}
}
@@ -525,6 +537,38 @@
return instance;
}
+// This function looks for the url pattern indicating that this request needs
+// to be forced into chrome frame.
+// This hack is required because window.open requests from Chrome don't have
+// the URL up front. The URL comes in much later when the renderer initiates a
+// top level navigation for the url passed into window.open.
+// The new page must be rendered in ChromeFrame to preserve the opener
+// relationship with its parent even if the new page does not have the chrome
+// meta tag.
+bool HandleAttachToExistingExternalTab(LPCWSTR url,
+ IInternetProtocol* protocol,
+ IInternetProtocolSink* prot_sink,
+ IBindCtx* bind_ctx) {
+ if (MatchPatternWide(url, kChromeFrameAttachTabPattern)) {
+ scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol);
+ if (!prot_data) {
+ // Pass NULL as the read function which indicates that always return EOF
+ // without calling the underlying protocol.
+ prot_data = new ProtData(protocol, NULL, url);
+ PutProtData(bind_ctx, prot_data);
+ }
+
+ prot_sink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType);
+
+ int data_flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
+ prot_sink->ReportData(data_flags, 0, 0);
+
+ prot_sink->ReportResult(S_OK, 0, NULL);
+ return true;
+ }
+ return false;
+}
+
// IInternetProtocol/Ex hooks.
STDMETHODIMP Hook_Start(InternetProtocol_Start_Fn orig_start,
IInternetProtocol* protocol, LPCWSTR url, IInternetProtocolSink* prot_sink,
@@ -542,6 +586,10 @@
return orig_start(protocol, url, prot_sink, bind_info, flags, reserved);
}
+ if (HandleAttachToExistingExternalTab(url, protocol, prot_sink, bind_ctx)) {
+ return S_OK;
+ }
+
if (IsCFRequest(bind_ctx)) {
return orig_start(protocol, url, prot_sink, bind_info, flags, reserved);
}
@@ -589,6 +637,10 @@
return orig_start_ex(protocol, uri, prot_sink, bind_info, flags, reserved);
}
+ if (HandleAttachToExistingExternalTab(url, protocol, prot_sink, bind_ctx)) {
+ return S_OK;
+ }
+
if (IsCFRequest(bind_ctx)) {
return orig_start_ex(protocol, uri, prot_sink, bind_info, flags, reserved);
}
@@ -620,15 +672,51 @@
STDMETHODIMP Hook_Read(InternetProtocol_Read_Fn orig_read,
IInternetProtocol* protocol, void* buffer, ULONG size, ULONG* size_read) {
DCHECK(orig_read);
+ HRESULT hr = E_FAIL;
+
scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol);
if (!prot_data) {
- return orig_read(protocol, buffer, size, size_read);
+ hr = orig_read(protocol, buffer, size, size_read);
+ return hr;
}
- HRESULT hr = prot_data->Read(buffer, size, size_read);
+ if (prot_data->is_attach_external_tab_request()) {
+ // return EOF always.
+ if (size_read)
+ *size_read = 0;
+ return S_FALSE;
+ }
+
+ hr = prot_data->Read(buffer, size, size_read);
return hr;
}
+STDMETHODIMP Hook_LockRequest(InternetProtocol_LockRequest_Fn orig_req,
+ IInternetProtocol* protocol, DWORD options) {
+ DCHECK(orig_req);
+
+ scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol);
+ if (prot_data && prot_data->is_attach_external_tab_request()) {
+ prot_data->AddRef();
+ return S_OK;
+ }
+
+ return orig_req(protocol, options);
+}
+
+STDMETHODIMP Hook_UnlockRequest(InternetProtocol_UnlockRequest_Fn orig_req,
+ IInternetProtocol* protocol) {
+ DCHECK(orig_req);
+
+ scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol);
+ if (prot_data && prot_data->is_attach_external_tab_request()) {
+ prot_data->Release();
+ return S_OK;
+ }
+
+ return orig_req(protocol);
+}
+
// Patching / Hooking code.
class FakeProtocol : public CComObjectRootEx<CComSingleThreadModel>,
public IInternetProtocol {
« no previous file with comments | « chrome_frame/protocol_sink_wrap.h ('k') | chrome_frame/test/util_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698