| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_FRAME_URLMON_MONIKER_H_ | |
| 6 #define CHROME_FRAME_URLMON_MONIKER_H_ | |
| 7 | |
| 8 #include <atlbase.h> | |
| 9 #include <atlcom.h> | |
| 10 #include <urlmon.h> | |
| 11 #include <string> | |
| 12 | |
| 13 #include "base/lazy_instance.h" | |
| 14 #include "base/logging.h" | |
| 15 #include "base/threading/thread_local.h" | |
| 16 #include "base/win/scoped_variant.h" | |
| 17 #include "chrome_frame/utils.h" | |
| 18 | |
| 19 // This file contains classes that are used to cache the contents of a top-level | |
| 20 // http request (not for sub frames) while that request is parsed for the | |
| 21 // presence of a meta tag indicating that the page should be rendered in CF. | |
| 22 | |
| 23 // Here are a few scenarios we handle and how the classes come to play. | |
| 24 | |
| 25 // | |
| 26 // Scenario 1: Non CF url navigation through address bar (www.msn.com) | |
| 27 // - Bho::BeforeNavigate - top level url = www.msn.com | |
| 28 // - MSHTML -> MonikerPatch::BindToStorage. | |
| 29 // (IEFrame starts this by calling mshtml!*SuperNavigate*) | |
| 30 // - check if the url is a top level url | |
| 31 // - iff the url is a top level url, we switch in our own callback object | |
| 32 // and hook it up to the bind context (BSCBStorageBind) | |
| 33 // - otherwise just call the original | |
| 34 // - BSCBStorageBind::OnDataAvailable - sniffs data and determines that the | |
| 35 // renderer is not chrome. Goes into pass through mode. | |
| 36 // - The page loads in mshtml. | |
| 37 // | |
| 38 | |
| 39 // | |
| 40 // Scenario 2: CF navigation through address bar URL | |
| 41 // - Bho::BeforeNavigate - top level url = http://wave.google.com/ | |
| 42 // - MSHTML -> MonikerPatch::BindToStorage. | |
| 43 // (IEFrame starts this by calling mshtml!*SuperNavigate*) | |
| 44 // - request_data is NULL | |
| 45 // - check if the url is a top level url | |
| 46 // - iff the url is a top level url, we switch in our own callback object | |
| 47 // and hook it up to the bind context (BSCBStorageBind) | |
| 48 // - BSCBStorageBind::OnDataAvailable - sniffs data and determines that the | |
| 49 // renderer is chrome. It then registers a special bind context param and | |
| 50 // sets a magic clip format in the format_etc. Then goes into pass through | |
| 51 // mode. | |
| 52 // - mshtml looks at the clip format and re-issues the navigation with the | |
| 53 // same bind context. Also returns INET_E_TERMINATED_BIND so that same | |
| 54 // underlying transaction objects are used. | |
| 55 // - IEFrame -> MonikerPatch::BindToStorage | |
| 56 // - We check for the special bind context param and instantiate and | |
| 57 // return our ActiveDoc | |
| 58 | |
| 59 // | |
| 60 // Scenario 3: CF navigation through mshtml link | |
| 61 // Same as scenario #2. | |
| 62 // | |
| 63 | |
| 64 // | |
| 65 // Scenario 4: CF navigation through link click in chrome loads non CF page | |
| 66 // - Link click comes to ChromeActiveDocument::OnOpenURL | |
| 67 // - web_browser->Navigate with URL | |
| 68 // - [Scenario 1] | |
| 69 // | |
| 70 | |
| 71 // | |
| 72 // Scenario 5: CF navigation through link click in chrome loads CF page | |
| 73 // - Link click comes to ChromeActiveDocument::OnOpenURL | |
| 74 // - web_browser->Navigate with URL | |
| 75 // - [Scenario 2] | |
| 76 // | |
| 77 | |
| 78 // This class is the link between a few static, moniker related functions to | |
| 79 // the bho. The specific services needed by those functions are abstracted into | |
| 80 // this interface for easier testability. | |
| 81 class NavigationManager { | |
| 82 public: | |
| 83 NavigationManager() { | |
| 84 } | |
| 85 | |
| 86 // Returns the Bho instance for the current thread. This is returned from | |
| 87 // TLS. Returns NULL if no instance exists on the current thread. | |
| 88 static NavigationManager* GetThreadInstance(); | |
| 89 | |
| 90 void RegisterThreadInstance(); | |
| 91 void UnregisterThreadInstance(); | |
| 92 | |
| 93 virtual ~NavigationManager() { | |
| 94 DCHECK(GetThreadInstance() != this); | |
| 95 } | |
| 96 | |
| 97 // Returns the url of the current top level navigation. | |
| 98 const std::wstring& url() const { | |
| 99 return url_; | |
| 100 } | |
| 101 | |
| 102 // Called to set the current top level URL that's being navigated to. | |
| 103 void set_url(const wchar_t* url) { | |
| 104 DVLOG(1) << __FUNCTION__ << " " << url; | |
| 105 url_ = url; | |
| 106 } | |
| 107 | |
| 108 // Returns the referrer header value of the current top level navigation. | |
| 109 const std::string& referrer() const { | |
| 110 return referrer_; | |
| 111 } | |
| 112 | |
| 113 void set_referrer(const std::string& referrer) { | |
| 114 referrer_ = referrer; | |
| 115 } | |
| 116 | |
| 117 // Return true if this is a URL that represents a top-level | |
| 118 // document that might have to be rendered in CF. | |
| 119 virtual bool IsTopLevelUrl(const wchar_t* url); | |
| 120 | |
| 121 // Called when we've detected the http-equiv meta tag in the current page | |
| 122 // and need to switch over from mshtml to CF. | |
| 123 virtual HRESULT NavigateToCurrentUrlInCF(IBrowserService* browser); | |
| 124 | |
| 125 void set_post_data(VARIANT* post_data) { | |
| 126 post_data_.Reset(); | |
| 127 if (post_data) { | |
| 128 if (V_VT(post_data) == (VT_BYREF | VT_VARIANT)) { | |
| 129 post_data_.Set(*post_data->pvarVal); | |
| 130 } else { | |
| 131 NOTREACHED() << "unexpected type for post_data: " | |
| 132 << std::hex << post_data->vt; | |
| 133 } | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 const base::win::ScopedVariant& post_data() const { | |
| 138 return post_data_; | |
| 139 } | |
| 140 | |
| 141 void set_headers(VARIANT* headers) { | |
| 142 headers_.Reset(); | |
| 143 if (headers) { | |
| 144 headers_ = *headers; | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 const base::win::ScopedVariant& headers() const { | |
| 149 return headers_; | |
| 150 } | |
| 151 | |
| 152 protected: | |
| 153 std::string referrer_; | |
| 154 std::wstring url_; | |
| 155 base::win::ScopedVariant post_data_; | |
| 156 base::win::ScopedVariant headers_; | |
| 157 | |
| 158 static base::LazyInstance<base::ThreadLocalPointer<NavigationManager> > | |
| 159 thread_singleton_; | |
| 160 | |
| 161 private: | |
| 162 DISALLOW_COPY_AND_ASSIGN(NavigationManager); | |
| 163 }; | |
| 164 | |
| 165 // static-only class that manages an IMoniker patch. | |
| 166 // We need this patch to stay in the loop when top-level HTML content is | |
| 167 // downloaded that might have the CF http-equiv meta tag. | |
| 168 // When we detect candidates for those requests, we add our own callback | |
| 169 // object (as explained at the top of this file) and use it to cache the | |
| 170 // original document contents in order to avoid multiple network trips | |
| 171 // if we need to switch the renderer over to CF. | |
| 172 class MonikerPatch { | |
| 173 MonikerPatch() {} // no instances should be created of this class. | |
| 174 public: | |
| 175 // Patches two IMoniker methods, BindToObject and BindToStorage. | |
| 176 static bool Initialize(); | |
| 177 | |
| 178 // Nullifies the IMoniker patches. | |
| 179 static void Uninitialize(); | |
| 180 | |
| 181 // Typedefs for IMoniker methods. | |
| 182 typedef HRESULT (STDMETHODCALLTYPE* IMoniker_BindToObject_Fn)(IMoniker* me, | |
| 183 IBindCtx* bind_ctx, IMoniker* to_left, REFIID iid, void** obj); | |
| 184 typedef HRESULT (STDMETHODCALLTYPE* IMoniker_BindToStorage_Fn)(IMoniker* me, | |
| 185 IBindCtx* bind_ctx, IMoniker* to_left, REFIID iid, void** obj); | |
| 186 | |
| 187 static STDMETHODIMP BindToObject(IMoniker_BindToObject_Fn original, | |
| 188 IMoniker* me, IBindCtx* bind_ctx, | |
| 189 IMoniker* to_left, REFIID iid, void** obj); | |
| 190 | |
| 191 static STDMETHODIMP BindToStorage(IMoniker_BindToStorage_Fn original, | |
| 192 IMoniker* me, IBindCtx* bind_ctx, | |
| 193 IMoniker* to_left, REFIID iid, void** obj); | |
| 194 }; | |
| 195 | |
| 196 extern wchar_t* kChromeRequestParam; | |
| 197 | |
| 198 #endif // CHROME_FRAME_URLMON_MONIKER_H_ | |
| OLD | NEW |