diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 23:41:56 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 23:41:56 +0000 |
commit | aa2cf38beabe222641b145e1cf985c72acd46c1e (patch) | |
tree | 9859b7141aba180524b6792dc980e7fe9f24ed75 /chrome_frame/http_negotiate.cc | |
parent | 022001851f2f6be890f9b44c49fa45ea38fa80b2 (diff) | |
download | chromium_src-aa2cf38beabe222641b145e1cf985c72acd46c1e.zip chromium_src-aa2cf38beabe222641b145e1cf985c72acd46c1e.tar.gz chromium_src-aa2cf38beabe222641b145e1cf985c72acd46c1e.tar.bz2 |
Fix a bug where in having ChromeFrame installed on the machine would cause a non chrome frame
email site to automatically logout after logging in. ChromeFrame appends the chromeframe string
to the user agent to outgoing requests initiated from IE. However this was only done in the
protocol sink patch for top level requests. Sub requests would carry the IE user agent which
in this case would cause the web server to get confused and drop the connection.
Fix is to resurrent the IHttpNegotiate vtable patch for the protocol patch as well.
Removed the code which read the patch method from the registry and turned on the moniker
or the httpequiv patch. It is unlikely that we will need this in the future. Cleaned
up the http negotiate patch by removing references to the navigation manager and the
ReportProgress patch which is not needed anymore.
Fixes bug http://code.google.com/p/chromium/issues/detail?id=60745
Bug=60745
Review URL: http://codereview.chromium.org/4247001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64688 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/http_negotiate.cc')
-rw-r--r-- | chrome_frame/http_negotiate.cc | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/chrome_frame/http_negotiate.cc b/chrome_frame/http_negotiate.cc index cc6155b..9d8344e 100644 --- a/chrome_frame/http_negotiate.cc +++ b/chrome_frame/http_negotiate.cc @@ -39,20 +39,6 @@ BEGIN_VTABLE_PATCHES(IHttpNegotiate) HttpNegotiatePatch::BeginningTransaction) END_VTABLE_PATCHES() -static const int kBindStatusCallbackStartBindingIndex = 3; - -BEGIN_VTABLE_PATCHES(IBindStatusCallback) - VTABLE_PATCH_ENTRY(kBindStatusCallbackStartBindingIndex, - HttpNegotiatePatch::StartBinding) -END_VTABLE_PATCHES() - -static const int kInternetProtocolSinkReportProgressIndex = 4; - -BEGIN_VTABLE_PATCHES(IInternetProtocolSink) - VTABLE_PATCH_ENTRY(kInternetProtocolSinkReportProgressIndex, - HttpNegotiatePatch::ReportProgress) -END_VTABLE_PATCHES() - namespace { class SimpleBindStatusCallback : public CComObjectRootEx<CComSingleThreadModel>, @@ -170,25 +156,6 @@ std::string ReplaceOrAddUserAgent(LPCWSTR headers, return new_headers; } -HRESULT GetBrowserServiceFromProtocolSink(IInternetProtocolSink* sink, - IBrowserService** browser_service) { - DCHECK(browser_service); - // When fetching a page for the first time (not cached), we can query the - // sink directly for IID_IShellBrowser to get the browser service. - HRESULT hr = DoQueryService(IID_IShellBrowser, sink, browser_service); - if (FAILED(hr)) { - // When the request is being served up from the cache, we have to take - // a different route via IID_ITargetFrame2. - ScopedComPtr<IWebBrowser2> browser2; - hr = DoQueryService(IID_ITargetFrame2, sink, browser2.Receive()); - if (browser2) { - hr = DoQueryService(IID_IShellBrowser, browser2, browser_service); - } - } - - return hr; -} - HttpNegotiatePatch::HttpNegotiatePatch() { } @@ -246,19 +213,6 @@ HRESULT HttpNegotiatePatch::PatchHttpNegotiate(IUnknown* to_patch) { DLOG(WARNING) << base::StringPrintf("IHttpNegotiate not supported 0x%08X", hr); } - - ScopedComPtr<IBindStatusCallback> bscb; - hr = bscb.QueryFrom(to_patch); - - if (bscb) { - hr = vtable_patch::PatchInterfaceMethods(bscb, - IBindStatusCallback_PatchInfo); - DLOG_IF(ERROR, FAILED(hr)) - << base::StringPrintf("BindStatusCallback patch failed 0x%08X", hr); - } else { - DLOG(WARNING) << base::StringPrintf( - "IBindStatusCallback not supported 0x%08X", hr); - } return hr; } @@ -274,35 +228,6 @@ HRESULT HttpNegotiatePatch::BeginningTransaction( DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error"; return hr; } - - NavigationManager* mgr = NavigationManager::GetThreadInstance(); - if (mgr && mgr->IsTopLevelUrl(url)) { - ScopedComPtr<IWebBrowser2> browser2; - DoQueryService(IID_ITargetFrame2, me, browser2.Receive()); - if (browser2) { - VARIANT_BOOL is_top_level = VARIANT_FALSE; - browser2->get_TopLevelContainer(&is_top_level); - - if (is_top_level != VARIANT_FALSE) { - std::string referrer = FindReferrerFromHeaders(headers, - *additional_headers); - // When we switch from IE to CF the BeginningTransaction function is - // called twice. The first call contains the referrer while the - // second call does not. We set the referrer only if the URL in the - // navigation manager changes. The URL in the navigation manager - // is reset in BeforeNavigate2 - if (!referrer.empty()) { - DCHECK(mgr->referrer().empty()); - mgr->set_referrer(referrer); - } - } - } else { - DVLOG(1) << "No IWebBrowser2"; - } - } else { - DVLOG(1) << "No NavigationManager"; - } - std::string updated(AppendCFUserAgentString(headers, *additional_headers)); *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemRealloc( *additional_headers, (updated.length() + 1) * sizeof(wchar_t))); @@ -310,162 +235,3 @@ HRESULT HttpNegotiatePatch::BeginningTransaction( return S_OK; } -// static -HRESULT HttpNegotiatePatch::StartBinding( - IBindStatusCallback_StartBinding_Fn original, - IBindStatusCallback* me, DWORD reserved, IBinding* binding) { - ScopedComPtr<IBinding> local_binding(binding); - ScopedComPtr<IInternetProtocolSink> protocol_sink; - - HRESULT hr = protocol_sink.QueryFrom(local_binding); - if (FAILED(hr) || !protocol_sink) { - DLOG(WARNING) << "Failed to get IInternetProtocolSink from IBinding: " - << hr; - } else { - if (!IS_PATCHED(IInternetProtocolSink)) { - hr = vtable_patch::PatchInterfaceMethods(protocol_sink, - IInternetProtocolSink_PatchInfo); - DCHECK(SUCCEEDED(hr)); - // Now that we've gotten to the protocol sink, - // we don't need this patch anymore. - HRESULT hr_unpatch = vtable_patch::UnpatchInterfaceMethods( - IBindStatusCallback_PatchInfo); - DCHECK(SUCCEEDED(hr_unpatch)); - } - - DLOG_IF(WARNING, FAILED(hr)) - << "Failed to patch IInternetProtocolSink from IBinding: " << hr; - } - - hr = original(me, reserved, binding); - return hr; -} - -// static -HRESULT HttpNegotiatePatch::ReportProgress( - IInternetProtocolSink_ReportProgress_Fn original, IInternetProtocolSink* me, - ULONG status_code, LPCWSTR status_text) { - DVLOG(1) << __FUNCTION__ - << base::StringPrintf(" %i %ls", status_code, status_text); - bool updated_mime_type = false; - - if (status_code == BINDSTATUS_MIMETYPEAVAILABLE || - status_code == BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE || - status_code == LOCAL_BINDSTATUS_SERVER_MIMETYPEAVAILABLE) { - DCHECK(lstrlenW(status_text)); - bool render_in_chrome_frame = false; - bool is_top_level_request = !IsSubFrameRequest(me); - // NOTE: After switching over to using the onhttpequiv notification from - // mshtml we can expect to see sub frames being created even before the - // owning document has completed loading. In particular frames whose - // source is about:blank. - - if (is_top_level_request) { - ScopedComPtr<IBrowserService> browser; - GetBrowserServiceFromProtocolSink(me, browser.Receive()); - if (browser) { - render_in_chrome_frame = CheckForCFNavigation(browser, true); - } - - DVLOG_IF(1, !render_in_chrome_frame) << " - browser not tagged"; - - if (!render_in_chrome_frame) { - // Check to see if we need to alter the mime type that gets reported - // by inspecting the raw header information: - ScopedComPtr<IWinInetHttpInfo> win_inet_http_info; - HRESULT hr = win_inet_http_info.QueryFrom(me); - - // Try slightly harder if we couldn't QI directly. - if (!win_inet_http_info || FAILED(hr)) { - hr = DoQueryService(IID_IWinInetHttpInfo, me, - win_inet_http_info.Receive()); - DLOG_IF(WARNING, FAILED(hr)) << "Failed to get IWinInetHttpInfo"; - } - - // Note that it has been observed that getting an IWinInetHttpInfo will - // fail if we are loading a page like about:blank that isn't loaded via - // wininet. - if (win_inet_http_info) { - // We have headers: check to see if the server is requesting CF via - // the X-UA-Compatible: chrome=1 HTTP header. - // TODO(tommi): use HTTP_QUERY_CUSTOM instead of fetching and parsing - // all the headers. - std::string headers(GetRawHttpHeaders(win_inet_http_info)); - net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), - "\r\n"); - while (it.GetNext()) { - if (LowerCaseEqualsASCII(it.name_begin(), it.name_end(), - kUACompatibleHttpHeader)) { - std::string ua_value(StringToLowerASCII(it.values())); - if (ua_value.find("chrome=1") != std::string::npos) { - render_in_chrome_frame = true; - break; - } - } - } - } - } - } - - if (render_in_chrome_frame) { - if (IsTextHtmlMimeType(status_text)) { - DVLOG(1) << "- changing mime type to " << kChromeMimeType; - status_text = kChromeMimeType; - updated_mime_type = true; - } else { - DVLOG(1) << "- don't want to render " << status_text << " in cf"; - } - } - } - - if (updated_mime_type) { - // Report all crashes in the exception handler as we updated the mime type. - // Note that this avoids having the VEH report a crash if an SEH earlier in - // the chain handles the exception. - ExceptionBarrier barrier; - return original(me, status_code, status_text); - } else { - // Only report exceptions caused within ChromeFrame in this context. - ExceptionBarrierReportOnlyModule barrier; - return original(me, status_code, status_text); - } -} - -STDMETHODIMP UserAgentAddOn::BeginningTransaction(LPCWSTR url, LPCWSTR headers, - DWORD reserved, - LPWSTR* additional_headers) { - HRESULT hr = S_OK; - if (delegate_) { - hr = delegate_->BeginningTransaction(url, headers, reserved, - additional_headers); - } - - if (hr == S_OK) { - std::string updated_headers; - if (IsGcfDefaultRenderer() && - RENDERER_TYPE_CHROME_DEFAULT_RENDERER == RendererTypeForUrl(url)) { - // Replace the user-agent header with Chrome's. - updated_headers = ReplaceOrAddUserAgent(*additional_headers, - http_utils::GetChromeUserAgent()); - } else { - // Add "chromeframe" user-agent string. - updated_headers = AppendCFUserAgentString(headers, *additional_headers); - } - - *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemRealloc( - *additional_headers, (updated_headers.length() + 1) * sizeof(wchar_t))); - lstrcpyW(*additional_headers, ASCIIToWide(updated_headers).c_str()); - } - return hr; -} - -STDMETHODIMP UserAgentAddOn::OnResponse(DWORD response_code, - LPCWSTR response_headers, LPCWSTR request_headers, - LPWSTR* additional_headers) { - HRESULT hr = S_OK; - if (delegate_) { - hr = delegate_->OnResponse(response_code, response_headers, request_headers, - additional_headers); - } - return hr; -} |