diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-17 04:02:58 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-17 04:02:58 +0000 |
commit | aaf124502e4c86acf98b88998fca3afcdb88a234 (patch) | |
tree | 3e163bb2cef2512464d8a3f54f2d2f42918a8f48 /chrome_frame/protocol_sink_wrap.cc | |
parent | 962b98214d0ca8e8db14ae83ccb79667ec440eac (diff) | |
download | chromium_src-aaf124502e4c86acf98b88998fca3afcdb88a234.zip chromium_src-aaf124502e4c86acf98b88998fca3afcdb88a234.tar.gz chromium_src-aaf124502e4c86acf98b88998fca3afcdb88a234.tar.bz2 |
BUG=47879
Review URL: http://codereview.chromium.org/2824057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52806 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/protocol_sink_wrap.cc')
-rw-r--r-- | chrome_frame/protocol_sink_wrap.cc | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/chrome_frame/protocol_sink_wrap.cc b/chrome_frame/protocol_sink_wrap.cc index 716e308..f5ed710 100644 --- a/chrome_frame/protocol_sink_wrap.cc +++ b/chrome_frame/protocol_sink_wrap.cc @@ -91,6 +91,48 @@ ScopedComPtr<IInternetProtocolSink> ProtocolSinkWrap::CreateNewSink( return ScopedComPtr<IInternetProtocolSink>(new_sink); } +HRESULT ProtocolSinkWrap::ObtainServiceProvider() { + HRESULT hr = S_OK; + if (!delegate_service_provider_) { + hr = delegate_service_provider_.QueryFrom(delegate_); + } + return hr; +} + +HRESULT ProtocolSinkWrap::ObtainHttpNegotiate() { + if (UserAgentAddOn::has_delegate()) + return S_OK; + + HRESULT hr = ObtainServiceProvider(); + if (hr == S_OK) { + ScopedComPtr<IHttpNegotiate> http_negotiate; + hr = delegate_service_provider_->QueryService( + IID_IHttpNegotiate, + IID_IHttpNegotiate, + reinterpret_cast<void**>(http_negotiate.Receive())); + UserAgentAddOn::set_delegate(http_negotiate); + } + return hr; +} + +STDMETHODIMP ProtocolSinkWrap::QueryService(REFGUID guidService, REFIID riid, + void** ppvObject) { + // We really insist to append "chromeframe" user-agent header, even in the + // very unlikely case when delegate does not support IServiceProvider and/or + // IHttpNegotiate. + if (guidService == IID_IHttpNegotiate && riid == IID_IHttpNegotiate) { + ObtainHttpNegotiate(); + AddRef(); + *ppvObject = reinterpret_cast<void**>(static_cast<IHttpNegotiate*>(this)); + return S_OK; + } + + HRESULT hr = ObtainServiceProvider(); + if (hr == S_OK) + hr = delegate_service_provider_->QueryService(guidService, riid, ppvObject); + return hr; +} + // IInternetProtocolSink methods STDMETHODIMP ProtocolSinkWrap::Switch(PROTOCOLDATA* protocol_data) { HRESULT hr = E_FAIL; @@ -318,18 +360,27 @@ HRESULT ProtData::ReportProgress(IInternetProtocolSink* delegate, // TODO(stoyan): BINDSTATUS_RAWMIMETYPE case BINDSTATUS_MIMETYPEAVAILABLE: case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: - SaveSuggestedMimeType(status_text); - - ScopedComPtr<IWinInetHttpInfo> info; - info.QueryFrom(delegate); - renderer_type_ = DetermineRendererTypeFromMetaData(suggested_mime_type_, - url_, info); + // When Transaction is attached i.e. when existing BTS it terminated + // and "converted" to BTO, events will be re-fired for the new sink, + // but we may skip the renderer_type_ determination since it's already + // done. + if (renderer_type_ == UNDETERMINED) { + SaveSuggestedMimeType(status_text); + // This may seem awkward. CBinding's implementation of IWinInetHttpInfo + // will forward to CTransaction that will forward to the real protocol. + // We may ask CTransaction (our protocol_ member) for IWinInetHttpInfo. + ScopedComPtr<IWinInetHttpInfo> info; + info.QueryFrom(delegate); + renderer_type_ = DetermineRendererTypeFromMetaData(suggested_mime_type_, + url_, info); + } if (renderer_type_ == CHROME) { // Suggested mime type is "text/html" and we either have OptInUrl // or X-UA-Compatible HTTP headers. DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " << kChromeMimeType; + SaveReferrer(delegate); delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType); } else if (renderer_type_ == OTHER) { // Suggested mime type is not "text/html" - we are not interested in @@ -369,6 +420,7 @@ HRESULT ProtData::ReportData(IInternetProtocolSink* delegate, if (renderer_type_ == CHROME) { DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " << kChromeMimeType; + SaveReferrer(delegate); delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType); } @@ -446,6 +498,23 @@ void ProtData::FireSugestedMimeType(IInternetProtocolSink* delegate) { } } +void ProtData::SaveReferrer(IInternetProtocolSink* delegate) { + DCHECK_EQ(CHROME, renderer_type_); + ScopedComPtr<IWinInetHttpInfo> info; + info.QueryFrom(delegate); + DCHECK(info); + if (info) { + char buffer[4096] = {0}; + DWORD len = sizeof(buffer); + DWORD flags = 0; + HRESULT hr = info->QueryInfo( + HTTP_QUERY_REFERER | HTTP_QUERY_FLAG_REQUEST_HEADERS, + buffer, &len, &flags, 0); + if (hr == S_OK && len > 0) + referrer_.assign(buffer); + } +} + scoped_refptr<ProtData> ProtData::DataFromProtocol( IInternetProtocol* protocol) { scoped_refptr<ProtData> instance; |