OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <htiframe.h> | 5 #include <htiframe.h> |
6 #include <mshtml.h> | 6 #include <mshtml.h> |
7 | 7 |
8 #include "chrome_frame/protocol_sink_wrap.h" | 8 #include "chrome_frame/protocol_sink_wrap.h" |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 IInternetProtocolSink* sink, ProtData* data) { | 84 IInternetProtocolSink* sink, ProtData* data) { |
85 DCHECK(sink != NULL); | 85 DCHECK(sink != NULL); |
86 DCHECK(data != NULL); | 86 DCHECK(data != NULL); |
87 CComObject<ProtocolSinkWrap>* new_sink = NULL; | 87 CComObject<ProtocolSinkWrap>* new_sink = NULL; |
88 CComObject<ProtocolSinkWrap>::CreateInstance(&new_sink); | 88 CComObject<ProtocolSinkWrap>::CreateInstance(&new_sink); |
89 new_sink->delegate_ = sink; | 89 new_sink->delegate_ = sink; |
90 new_sink->prot_data_ = data; | 90 new_sink->prot_data_ = data; |
91 return ScopedComPtr<IInternetProtocolSink>(new_sink); | 91 return ScopedComPtr<IInternetProtocolSink>(new_sink); |
92 } | 92 } |
93 | 93 |
| 94 HRESULT ProtocolSinkWrap::ObtainServiceProvider() { |
| 95 HRESULT hr = S_OK; |
| 96 if (!delegate_service_provider_) { |
| 97 hr = delegate_service_provider_.QueryFrom(delegate_); |
| 98 } |
| 99 return hr; |
| 100 } |
| 101 |
| 102 HRESULT ProtocolSinkWrap::ObtainHttpNegotiate() { |
| 103 if (UserAgentAddOn::has_delegate()) |
| 104 return S_OK; |
| 105 |
| 106 HRESULT hr = ObtainServiceProvider(); |
| 107 if (hr == S_OK) { |
| 108 ScopedComPtr<IHttpNegotiate> http_negotiate; |
| 109 hr = delegate_service_provider_->QueryService( |
| 110 IID_IHttpNegotiate, |
| 111 IID_IHttpNegotiate, |
| 112 reinterpret_cast<void**>(http_negotiate.Receive())); |
| 113 UserAgentAddOn::set_delegate(http_negotiate); |
| 114 } |
| 115 return hr; |
| 116 } |
| 117 |
| 118 STDMETHODIMP ProtocolSinkWrap::QueryService(REFGUID guidService, REFIID riid, |
| 119 void** ppvObject) { |
| 120 // We really insist to append "chromeframe" user-agent header, even in the |
| 121 // very unlikely case when delegate does not support IServiceProvider and/or |
| 122 // IHttpNegotiate. |
| 123 if (guidService == IID_IHttpNegotiate && riid == IID_IHttpNegotiate) { |
| 124 ObtainHttpNegotiate(); |
| 125 AddRef(); |
| 126 *ppvObject = reinterpret_cast<void**>(static_cast<IHttpNegotiate*>(this)); |
| 127 return S_OK; |
| 128 } |
| 129 |
| 130 HRESULT hr = ObtainServiceProvider(); |
| 131 if (hr == S_OK) |
| 132 hr = delegate_service_provider_->QueryService(guidService, riid, ppvObject); |
| 133 return hr; |
| 134 } |
| 135 |
94 // IInternetProtocolSink methods | 136 // IInternetProtocolSink methods |
95 STDMETHODIMP ProtocolSinkWrap::Switch(PROTOCOLDATA* protocol_data) { | 137 STDMETHODIMP ProtocolSinkWrap::Switch(PROTOCOLDATA* protocol_data) { |
96 HRESULT hr = E_FAIL; | 138 HRESULT hr = E_FAIL; |
97 if (delegate_) | 139 if (delegate_) |
98 hr = delegate_->Switch(protocol_data); | 140 hr = delegate_->Switch(protocol_data); |
99 return hr; | 141 return hr; |
100 } | 142 } |
101 | 143 |
102 STDMETHODIMP ProtocolSinkWrap::ReportProgress(ULONG status_code, | 144 STDMETHODIMP ProtocolSinkWrap::ReportProgress(ULONG status_code, |
103 LPCWSTR status_text) { | 145 LPCWSTR status_text) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 break; | 353 break; |
312 | 354 |
313 case BINDSTATUS_SERVER_MIMETYPEAVAILABLE: | 355 case BINDSTATUS_SERVER_MIMETYPEAVAILABLE: |
314 has_server_mime_type_ = true; | 356 has_server_mime_type_ = true; |
315 SaveSuggestedMimeType(status_text); | 357 SaveSuggestedMimeType(status_text); |
316 return S_OK; | 358 return S_OK; |
317 | 359 |
318 // TODO(stoyan): BINDSTATUS_RAWMIMETYPE | 360 // TODO(stoyan): BINDSTATUS_RAWMIMETYPE |
319 case BINDSTATUS_MIMETYPEAVAILABLE: | 361 case BINDSTATUS_MIMETYPEAVAILABLE: |
320 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: | 362 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: |
321 SaveSuggestedMimeType(status_text); | 363 // When Transaction is attached i.e. when existing BTS it terminated |
322 | 364 // and "converted" to BTO, events will be re-fired for the new sink, |
323 ScopedComPtr<IWinInetHttpInfo> info; | 365 // but we may skip the renderer_type_ determination since it's already |
324 info.QueryFrom(delegate); | 366 // done. |
325 renderer_type_ = DetermineRendererTypeFromMetaData(suggested_mime_type_, | 367 if (renderer_type_ == UNDETERMINED) { |
326 url_, info); | 368 SaveSuggestedMimeType(status_text); |
| 369 // This may seem awkward. CBinding's implementation of IWinInetHttpInfo |
| 370 // will forward to CTransaction that will forward to the real protocol. |
| 371 // We may ask CTransaction (our protocol_ member) for IWinInetHttpInfo. |
| 372 ScopedComPtr<IWinInetHttpInfo> info; |
| 373 info.QueryFrom(delegate); |
| 374 renderer_type_ = DetermineRendererTypeFromMetaData(suggested_mime_type_, |
| 375 url_, info); |
| 376 } |
327 | 377 |
328 if (renderer_type_ == CHROME) { | 378 if (renderer_type_ == CHROME) { |
329 // Suggested mime type is "text/html" and we either have OptInUrl | 379 // Suggested mime type is "text/html" and we either have OptInUrl |
330 // or X-UA-Compatible HTTP headers. | 380 // or X-UA-Compatible HTTP headers. |
331 DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " | 381 DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " |
332 << kChromeMimeType; | 382 << kChromeMimeType; |
| 383 SaveReferrer(delegate); |
333 delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType); | 384 delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType); |
334 } else if (renderer_type_ == OTHER) { | 385 } else if (renderer_type_ == OTHER) { |
335 // Suggested mime type is not "text/html" - we are not interested in | 386 // Suggested mime type is not "text/html" - we are not interested in |
336 // this request anymore. | 387 // this request anymore. |
337 FireSugestedMimeType(delegate); | 388 FireSugestedMimeType(delegate); |
338 } else { | 389 } else { |
339 // Suggested mime type is "text/html"; We will try to sniff the | 390 // Suggested mime type is "text/html"; We will try to sniff the |
340 // HTML content in ReportData. | 391 // HTML content in ReportData. |
341 DCHECK_EQ(UNDETERMINED, renderer_type_); | 392 DCHECK_EQ(UNDETERMINED, renderer_type_); |
342 } | 393 } |
(...skipping 19 matching lines...) Expand all Loading... |
362 renderer_type_ = DetermineRendererType(buffer_, buffer_size_, last_chance); | 413 renderer_type_ = DetermineRendererType(buffer_, buffer_size_, last_chance); |
363 | 414 |
364 if (renderer_type_ == UNDETERMINED) { | 415 if (renderer_type_ == UNDETERMINED) { |
365 // do not report anything, we need more data. | 416 // do not report anything, we need more data. |
366 return S_OK; | 417 return S_OK; |
367 } | 418 } |
368 | 419 |
369 if (renderer_type_ == CHROME) { | 420 if (renderer_type_ == CHROME) { |
370 DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " | 421 DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " |
371 << kChromeMimeType; | 422 << kChromeMimeType; |
| 423 SaveReferrer(delegate); |
372 delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType); | 424 delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, kChromeMimeType); |
373 } | 425 } |
374 | 426 |
375 if (renderer_type_ == OTHER) { | 427 if (renderer_type_ == OTHER) { |
376 FireSugestedMimeType(delegate); | 428 FireSugestedMimeType(delegate); |
377 } | 429 } |
378 | 430 |
379 // This is the first data notification we forward, since up to now we hold | 431 // This is the first data notification we forward, since up to now we hold |
380 // the content received. | 432 // the content received. |
381 flags |= BSCF_FIRSTDATANOTIFICATION; | 433 flags |= BSCF_FIRSTDATANOTIFICATION; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 } | 491 } |
440 | 492 |
441 if (has_suggested_mime_type_) { | 493 if (has_suggested_mime_type_) { |
442 DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " | 494 DLOG(INFO) << "Forwarding BINDSTATUS_MIMETYPEAVAILABLE " |
443 << suggested_mime_type_; | 495 << suggested_mime_type_; |
444 delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, | 496 delegate->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, |
445 suggested_mime_type_); | 497 suggested_mime_type_); |
446 } | 498 } |
447 } | 499 } |
448 | 500 |
| 501 void ProtData::SaveReferrer(IInternetProtocolSink* delegate) { |
| 502 DCHECK_EQ(CHROME, renderer_type_); |
| 503 ScopedComPtr<IWinInetHttpInfo> info; |
| 504 info.QueryFrom(delegate); |
| 505 DCHECK(info); |
| 506 if (info) { |
| 507 char buffer[4096] = {0}; |
| 508 DWORD len = sizeof(buffer); |
| 509 DWORD flags = 0; |
| 510 HRESULT hr = info->QueryInfo( |
| 511 HTTP_QUERY_REFERER | HTTP_QUERY_FLAG_REQUEST_HEADERS, |
| 512 buffer, &len, &flags, 0); |
| 513 if (hr == S_OK && len > 0) |
| 514 referrer_.assign(buffer); |
| 515 } |
| 516 } |
| 517 |
449 scoped_refptr<ProtData> ProtData::DataFromProtocol( | 518 scoped_refptr<ProtData> ProtData::DataFromProtocol( |
450 IInternetProtocol* protocol) { | 519 IInternetProtocol* protocol) { |
451 scoped_refptr<ProtData> instance; | 520 scoped_refptr<ProtData> instance; |
452 AutoLock lock(datamap_lock_); | 521 AutoLock lock(datamap_lock_); |
453 ProtocolDataMap::iterator it = datamap_.find(protocol); | 522 ProtocolDataMap::iterator it = datamap_.find(protocol); |
454 if (datamap_.end() != it) | 523 if (datamap_.end() != it) |
455 instance = it->second; | 524 instance = it->second; |
456 return instance; | 525 return instance; |
457 } | 526 } |
458 | 527 |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 // Explicit release, otherwise ~CComObjectStackEx will complain about | 731 // Explicit release, otherwise ~CComObjectStackEx will complain about |
663 // outstanding reference to us, because it runs before ~FakeProtocol | 732 // outstanding reference to us, because it runs before ~FakeProtocol |
664 prot.transaction_.Release(); | 733 prot.transaction_.Release(); |
665 } | 734 } |
666 } | 735 } |
667 | 736 |
668 void TransactionHooks::RevertHooks() { | 737 void TransactionHooks::RevertHooks() { |
669 vtable_patch::UnpatchInterfaceMethods(CTransaction_PatchInfo); | 738 vtable_patch::UnpatchInterfaceMethods(CTransaction_PatchInfo); |
670 vtable_patch::UnpatchInterfaceMethods(CTransaction2_PatchInfo); | 739 vtable_patch::UnpatchInterfaceMethods(CTransaction2_PatchInfo); |
671 } | 740 } |
OLD | NEW |