| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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_PROTOCOL_SINK_WRAP_H_ | |
| 6 #define CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ | |
| 7 | |
| 8 #include <exdisp.h> | |
| 9 #include <urlmon.h> | |
| 10 #include <atlbase.h> | |
| 11 #include <atlcom.h> | |
| 12 | |
| 13 #include <map> | |
| 14 #include <string> | |
| 15 | |
| 16 #include "base/basictypes.h" | |
| 17 #include "base/memory/ref_counted.h" | |
| 18 #include "base/win/scoped_comptr.h" | |
| 19 #include "base/win/scoped_bstr.h" | |
| 20 #include "chrome_frame/chrome_frame_delegate.h" | |
| 21 #include "chrome_frame/http_negotiate.h" | |
| 22 #include "chrome_frame/ie8_types.h" | |
| 23 #include "chrome_frame/utils.h" | |
| 24 #include "chrome_frame/vtable_patch_manager.h" | |
| 25 | |
| 26 // Typedefs for IInternetProtocol and related methods that we patch. | |
| 27 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Start_Fn)( | |
| 28 IInternetProtocol* this_object, LPCWSTR url, | |
| 29 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, | |
| 30 DWORD flags, HANDLE_PTR reserved); | |
| 31 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Read_Fn)( | |
| 32 IInternetProtocol* this_object, void* buffer, ULONG size, | |
| 33 ULONG* size_read); | |
| 34 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_StartEx_Fn)( | |
| 35 IInternetProtocolEx* this_object, IUri* uri, | |
| 36 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, | |
| 37 DWORD flags, HANDLE_PTR reserved); | |
| 38 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_LockRequest_Fn)( | |
| 39 IInternetProtocol* this_object, DWORD options); | |
| 40 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_UnlockRequest_Fn)( | |
| 41 IInternetProtocol* this_object); | |
| 42 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Abort_Fn)( | |
| 43 IInternetProtocol* this_object, HRESULT hr, DWORD options); | |
| 44 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Terminate_Fn)( | |
| 45 IInternetProtocol* this_object, DWORD options); | |
| 46 | |
| 47 class ProtData; | |
| 48 | |
| 49 // A class to wrap protocol sink in IInternetProtocol::Start[Ex] for | |
| 50 // HTTP and HTTPS protocols. | |
| 51 // | |
| 52 // This is an alternative to a mime filter and we have to do this in order | |
| 53 // to inspect initial portion of HTML for 'chrome' meta tag and report | |
| 54 // a different mime type in that case. | |
| 55 // | |
| 56 // We implement several documented interfaces | |
| 57 // supported by the original sink provided by urlmon. There are a few | |
| 58 // undocumented interfaces that we have chosen not to implement | |
| 59 // but delegate simply the QI. | |
| 60 class ProtocolSinkWrap | |
| 61 : public CComObjectRootEx<CComMultiThreadModel>, | |
| 62 public IInternetProtocolSink { | |
| 63 public: | |
| 64 BEGIN_COM_MAP(ProtocolSinkWrap) | |
| 65 COM_INTERFACE_ENTRY(IInternetProtocolSink) | |
| 66 COM_INTERFACE_BLIND_DELEGATE() | |
| 67 END_COM_MAP() | |
| 68 | |
| 69 static base::win::ScopedComPtr<IInternetProtocolSink> CreateNewSink( | |
| 70 IInternetProtocolSink* sink, ProtData* prot_data); | |
| 71 | |
| 72 // Enables or disables activation of Chrome Frame via the X-UA-Compatible | |
| 73 // header or meta tag. The tag/header is respected by default. | |
| 74 static void set_ignore_xua(bool ignore_xua) { ignore_xua_ = ignore_xua; } | |
| 75 static bool ignore_xua() { return ignore_xua_; } | |
| 76 | |
| 77 // Apparently this has to be public, to satisfy COM_INTERFACE_BLIND_DELEGATE | |
| 78 IInternetProtocolSink* delegate() { | |
| 79 return delegate_; | |
| 80 } | |
| 81 | |
| 82 protected: | |
| 83 ProtocolSinkWrap(); | |
| 84 ~ProtocolSinkWrap(); | |
| 85 | |
| 86 private: | |
| 87 static bool ignore_xua_; | |
| 88 | |
| 89 // IInternetProtocolSink methods | |
| 90 STDMETHOD(Switch)(PROTOCOLDATA* protocol_data); | |
| 91 STDMETHOD(ReportProgress)(ULONG status_code, LPCWSTR status_text); | |
| 92 STDMETHOD(ReportData)(DWORD flags, ULONG progress, ULONG max_progress); | |
| 93 STDMETHOD(ReportResult)(HRESULT result, DWORD error, LPCWSTR result_text); | |
| 94 | |
| 95 // Remember original sink | |
| 96 base::win::ScopedComPtr<IInternetProtocolSink> delegate_; | |
| 97 base::win::ScopedComPtr<IServiceProvider> delegate_service_provider_; | |
| 98 scoped_refptr<ProtData> prot_data_; | |
| 99 DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap); | |
| 100 }; | |
| 101 | |
| 102 class ProtData : public base::RefCounted<ProtData> { | |
| 103 public: | |
| 104 ProtData(IInternetProtocol* protocol, InternetProtocol_Read_Fn read_fun, | |
| 105 const wchar_t* url); | |
| 106 ~ProtData(); | |
| 107 HRESULT Read(void* buffer, ULONG size, ULONG* size_read); | |
| 108 HRESULT ReportProgress(IInternetProtocolSink* delegate, | |
| 109 ULONG status_code, | |
| 110 LPCWSTR status_text); | |
| 111 HRESULT ReportData(IInternetProtocolSink* delegate, | |
| 112 DWORD flags, ULONG progress, ULONG max_progress); | |
| 113 HRESULT ReportResult(IInternetProtocolSink* delegate, HRESULT result, | |
| 114 DWORD error, LPCWSTR result_text); | |
| 115 void UpdateUrl(const wchar_t* url); | |
| 116 static scoped_refptr<ProtData> DataFromProtocol(IInternetProtocol* protocol); | |
| 117 | |
| 118 RendererType renderer_type() { | |
| 119 return renderer_type_; | |
| 120 } | |
| 121 | |
| 122 // Valid only if renderer_type_ is CHROME. | |
| 123 const std::string& referrer() const { | |
| 124 return referrer_; | |
| 125 } | |
| 126 | |
| 127 bool is_attach_external_tab_request() const { | |
| 128 return read_fun_ == NULL; | |
| 129 } | |
| 130 | |
| 131 // Removes the mapping between the protocol and the ProtData. | |
| 132 void Invalidate(); | |
| 133 | |
| 134 const std::wstring& url() const { | |
| 135 return url_; | |
| 136 } | |
| 137 | |
| 138 private: | |
| 139 typedef std::map<IInternetProtocol*, ProtData*> ProtocolDataMap; | |
| 140 static ProtocolDataMap datamap_; | |
| 141 static base::Lock datamap_lock_; | |
| 142 | |
| 143 // Url we are retrieving. Used for RendererTypeForUrl() only. | |
| 144 std::wstring url_; | |
| 145 // HTTP "Referrer" header if we detect are going to switch. | |
| 146 // We have to save and pass it to Chrome, so scripts can read it via DOM. | |
| 147 std::string referrer_; | |
| 148 | |
| 149 // Our gate to IInternetProtocol::Read() | |
| 150 IInternetProtocol* protocol_; | |
| 151 InternetProtocol_Read_Fn read_fun_; | |
| 152 | |
| 153 // What BINDSTATUS_MIMETYPEAVAILABLE and Co. tells us. | |
| 154 base::win::ScopedBstr suggested_mime_type_; | |
| 155 // At least one of the following has been received: | |
| 156 // BINDSTATUS_MIMETYPEAVAILABLE, | |
| 157 // MIMESTATUS_VERIFIEDMIMETYPEAVAILABLE | |
| 158 // BINDSTATUS_SERVER_MIMETYPEAVAILABLE | |
| 159 bool has_suggested_mime_type_; | |
| 160 // BINDSTATUS_SERVER_MIMETYPEAVAILABLE received, so we shall fire one. | |
| 161 bool has_server_mime_type_; | |
| 162 | |
| 163 RendererType renderer_type_; | |
| 164 | |
| 165 // Buffer for accumulated data including 1 extra for NULL-terminator | |
| 166 static const size_t kMaxContentSniffLength = 2 * 1024; | |
| 167 char buffer_[kMaxContentSniffLength + 1]; | |
| 168 unsigned long buffer_size_; // NOLINT | |
| 169 unsigned long buffer_pos_; // NOLINT | |
| 170 | |
| 171 HRESULT FillBuffer(); | |
| 172 void SaveSuggestedMimeType(LPCWSTR status_text); | |
| 173 void FireSuggestedMimeType(IInternetProtocolSink* delegate); | |
| 174 void SaveReferrer(IInternetProtocolSink* delegate); | |
| 175 }; | |
| 176 | |
| 177 struct TransactionHooks { | |
| 178 void InstallHooks(); | |
| 179 void RevertHooks(); | |
| 180 }; | |
| 181 | |
| 182 DECLSPEC_SELECTANY struct TransactionHooks g_trans_hooks; | |
| 183 | |
| 184 #endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ | |
| OLD | NEW |