diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-09 16:54:12 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-09 16:54:12 +0000 |
commit | ce2b9f923c23700d24658b5118ab9c1d2f330d8b (patch) | |
tree | bdd559fc120cc9b5e5111a5c53efc4e3e0184466 /chrome_frame/protocol_sink_wrap.h | |
parent | 78c7e2c68da0079869252bb464f4633373e5d067 (diff) | |
download | chromium_src-ce2b9f923c23700d24658b5118ab9c1d2f330d8b.zip chromium_src-ce2b9f923c23700d24658b5118ab9c1d2f330d8b.tar.gz chromium_src-ce2b9f923c23700d24658b5118ab9c1d2f330d8b.tar.bz2 |
A new way of hooking internet protocols.
TEST=chrome frame tests
Review URL: http://codereview.chromium.org/2620001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49265 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/protocol_sink_wrap.h')
-rw-r--r-- | chrome_frame/protocol_sink_wrap.h | 238 |
1 files changed, 75 insertions, 163 deletions
diff --git a/chrome_frame/protocol_sink_wrap.h b/chrome_frame/protocol_sink_wrap.h index 53812ba..2b8a08d0 100644 --- a/chrome_frame/protocol_sink_wrap.h +++ b/chrome_frame/protocol_sink_wrap.h @@ -16,6 +16,7 @@ #include "base/basictypes.h" #include "base/ref_counted.h" #include "base/scoped_comptr_win.h" +#include "base/scoped_bstr_win.h" #include "googleurl/src/gurl.h" #include "chrome_frame/chrome_frame_delegate.h" #include "chrome_frame/ie8_types.h" @@ -37,6 +38,15 @@ typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_StartEx_Fn)( typedef HRESULT (STDMETHODCALLTYPE* InternetProtocolRoot_Continue_Fn)( IInternetProtocolRoot* me, PROTOCOLDATA* data); + +enum RendererType { + UNDETERMINED, + CHROME, + OTHER +}; + +class ProtData; + // A class to wrap protocol sink in IInternetProtocol::Start[Ex] for // HTTP and HTTPS protocols. // @@ -50,199 +60,101 @@ typedef HRESULT (STDMETHODCALLTYPE* InternetProtocolRoot_Continue_Fn)( // but delegate simply the QI. class ProtocolSinkWrap : public CComObjectRootEx<CComMultiThreadModel>, - public IInternetProtocolSink, - public IInternetBindInfoEx, - public IServiceProvider, - public IAuthenticate, - public IInternetProtocolEx, - public IInternetPriority, - public IWrappedProtocol, - // public IPreBindingSupport, // undocumented - // public ITransProtocolSink, // Undocumented - // public ITransactionInternal, // undocumented - public IUriContainer { + public IInternetProtocolSink { public: BEGIN_COM_MAP(ProtocolSinkWrap) COM_INTERFACE_ENTRY(IInternetProtocolSink) - COM_INTERFACE_ENTRY(IInternetBindInfo) - COM_INTERFACE_ENTRY(IInternetBindInfoEx) - COM_INTERFACE_ENTRY(IServiceProvider) - COM_INTERFACE_ENTRY(IAuthenticate) - COM_INTERFACE_ENTRY(IInternetProtocolRoot) - COM_INTERFACE_ENTRY(IInternetProtocol) - COM_INTERFACE_ENTRY(IInternetProtocolEx) - COM_INTERFACE_ENTRY(IInternetPriority) - COM_INTERFACE_ENTRY(IWrappedProtocol) - COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(IUriContainer) COM_INTERFACE_BLIND_DELEGATE() END_COM_MAP() - ProtocolSinkWrap(); - virtual ~ProtocolSinkWrap(); - - bool Initialize(IInternetProtocol* protocol, - IInternetProtocolSink* original_sink, const wchar_t* url); - - // VTable patches the IInternetProtocol and IIntenetProtocolEx interface. - // Returns true on success. - static bool PatchProtocolHandlers(); - - // Unpatches the IInternetProtocol and IInternetProtocolEx interfaces. - static void UnpatchProtocolHandlers(); + static ScopedComPtr<IInternetProtocolSink> CreateNewSink( + IInternetProtocolSink* sink, ProtData* prot_data); - // IInternetProtocol/Ex patches. - static STDMETHODIMP OnStart(InternetProtocol_Start_Fn orig_start, - IInternetProtocol* protocol, LPCWSTR url, - IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, - DWORD flags, HANDLE_PTR reserved); - - static STDMETHODIMP OnStartEx( - InternetProtocol_StartEx_Fn orig_start_ex, IInternetProtocolEx* protocol, - IUri* uri, IInternetProtocolSink* prot_sink, - IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); + // Apparently this has to be public, to satisfy COM_INTERFACE_BLIND_DELEGATE + IInternetProtocolSink* delegate() { + return delegate_; + } - static STDMETHODIMP OnRead(InternetProtocol_Read_Fn orig_read, - IInternetProtocol* protocol, void* buffer, ULONG size, ULONG* size_read); + protected: + ProtocolSinkWrap(); + ~ProtocolSinkWrap(); + private: // IInternetProtocolSink methods STDMETHOD(Switch)(PROTOCOLDATA* protocol_data); STDMETHOD(ReportProgress)(ULONG status_code, LPCWSTR status_text); STDMETHOD(ReportData)(DWORD flags, ULONG progress, ULONG max_progress); STDMETHOD(ReportResult)(HRESULT result, DWORD error, LPCWSTR result_text); - // IInternetBindInfoEx - STDMETHOD(GetBindInfo)(DWORD* flags, BINDINFO* bind_info); - STDMETHOD(GetBindString)(ULONG string_type, LPOLESTR* string_array, - ULONG array_size, ULONG* size_returned); - STDMETHOD(GetBindInfoEx)(DWORD *flags, BINDINFO* bind_info, - DWORD* bindf2, DWORD *reserved); - - // IServiceProvider - STDMETHOD(QueryService)(REFGUID service_guid, REFIID riid, void** service); - - // IAuthenticate - STDMETHOD(Authenticate)(HWND* window, LPWSTR* user_name, LPWSTR* password); - - // IInternetProtocolEx - STDMETHOD(Start)(LPCWSTR url, IInternetProtocolSink *protocol_sink, - IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); - STDMETHOD(Continue)(PROTOCOLDATA* protocol_data); - STDMETHOD(Abort)(HRESULT reason, DWORD options); - STDMETHOD(Terminate)(DWORD options); - STDMETHOD(Suspend)(); - STDMETHOD(Resume)(); - STDMETHOD(Read)(void *buffer, ULONG size, ULONG* size_read); - STDMETHOD(Seek)(LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER* new_pos); - STDMETHOD(LockRequest)(DWORD options); - STDMETHOD(UnlockRequest)(); - STDMETHOD(StartEx)(IUri* uri, IInternetProtocolSink* protocol_sink, - IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); - - // IInternetPriority - STDMETHOD(SetPriority)(LONG priority); - STDMETHOD(GetPriority)(LONG* priority); - - // IWrappedProtocol - STDMETHOD(GetWrapperCode)(LONG *code, DWORD_PTR reserved); - - // public IUriContainer - STDMETHOD(GetIUri)(IUri** uri); - - // IPreBindingSupport, // undocumented - // ITransProtocolSink, // Undocumented - // ITransactionInternal, // undocumented - - IInternetProtocolSink* delegate() const { - return delegate_; - } + // Remember original sink + ScopedComPtr<IInternetProtocolSink> delegate_; + scoped_refptr<ProtData> prot_data_; + DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap); +}; - protected: - enum RendererType { - UNDETERMINED, - CHROME, - OTHER - }; - - typedef std::map<IInternetProtocol*, ProtocolSinkWrap*> ProtocolSinkMap; - static const int kMaxContentSniffLength = 1024; - - static scoped_refptr<ProtocolSinkWrap> InstanceFromProtocol( - IInternetProtocol* protocol); - static ScopedComPtr<IInternetProtocolSink> MaybeWrapSink( - IInternetProtocol* protocol, IInternetProtocolSink* prot_sink, - const wchar_t* url); - - void DetermineRendererType(); - - HRESULT OnReadImpl(void* buffer, ULONG size, ULONG* size_read, - InternetProtocol_Read_Fn orig_read); - - // This function determines whether the current request should be handled - // by Chrome. If yes it reports the mime type as application/chromepage, - // which ensures that the ChromeFrame is instantiated for handling this - // request. - // Returns S_OK on success. - HRESULT CheckAndReportChromeMimeTypeForRequest(); - - bool is_undetermined() const { - return (UNDETERMINED == renderer_type_); - } - RendererType renderer_type() const { +class ProtData : public base::RefCounted<ProtData> { + public: + ProtData(IInternetProtocol* protocol, InternetProtocol_Read_Fn read_fun, + const wchar_t* url); + ~ProtData(); + HRESULT Read(void* buffer, ULONG size, ULONG* size_read); + HRESULT ReportProgress(IInternetProtocolSink* delegate, + ULONG status_code, + LPCWSTR status_text); + HRESULT ReportData(IInternetProtocolSink* delegate, + DWORD flags, ULONG progress, ULONG max_progress); + HRESULT ReportResult(IInternetProtocolSink* delegate, HRESULT result, + DWORD error, LPCWSTR result_text); + void UpdateUrl(const wchar_t* url); + static scoped_refptr<ProtData> DataFromProtocol(IInternetProtocol* protocol); + + RendererType renderer_type() { return renderer_type_; } - // Creates an instance of the specified protocol handler and returns the - // IInternetProtocol interface pointer. - // Returns S_OK on success. - static HRESULT CreateProtocolHandlerInstance(const CLSID& clsid, - IInternetProtocol** protocol); - - // Helper function for patching the VTable of the IInternetProtocol - // interface. It instantiates the object identified by the protocol_clsid - // parameter and patches its VTable. - // Returns S_OK on success. - static HRESULT PatchProtocolMethods( - const CLSID& protocol_clsid, - vtable_patch::MethodPatchInfo* protocol_patch_info, - vtable_patch::MethodPatchInfo* protocol_ex_patch_info); - - // WARNING: Don't use GURL variables here. Please see - // http://b/issue?id=2102171 for details. - - // Remember original sink - ScopedComPtr<IInternetProtocolSink> delegate_; + private: + typedef std::map<IInternetProtocol*, ProtData*> ProtocolDataMap; + static ProtocolDataMap datamap_; + static Lock datamap_lock_; - // Cannot take a reference on the protocol. + // Url we are retrieving. Used for IsOptInUrl() only. + std::wstring url_; + // Our gate to IInternetProtocol::Read() IInternetProtocol* protocol_; + InternetProtocol_Read_Fn read_fun_; + + // What BINDSTATUS_MIMETYPEAVAILABLE and Co. tells us. + ScopedBstr suggested_mime_type_; + // At least one of the following has been received: + // BINDSTATUS_MIMETYPEAVAILABLE, + // MIMESTATUS_VERIFIEDMIMETYPEAVAILABLE + // BINDSTATUS_SERVER_MIMETYPEAVAILABLE + bool has_suggested_mime_type_; + // BINDSTATUS_SERVER_MIMETYPEAVAILABLE received, so we shall fire one. + bool has_server_mime_type_; + + // Did we received ReportData() + bool report_data_received_; RendererType renderer_type_; // Buffer for accumulated data including 1 extra for NULL-terminator + static const size_t kMaxContentSniffLength = 2 * 1024; char buffer_[kMaxContentSniffLength + 1]; unsigned long buffer_size_; // NOLINT unsigned long buffer_pos_; // NOLINT - // Accumulated result - bool is_saved_result_; - HRESULT result_code_; - DWORD result_error_; - std::wstring result_text_; - // For tracking re-entrency and preventing duplicate Read()s from - // distorting the outcome of ReportData. - int report_data_recursiveness_; - - static ProtocolSinkMap sink_map_; - // TODO(joshia): Replace with Lock - static CComAutoCriticalSection sink_map_lock_; - - std::wstring url_; - - // Set to true if we are in the context of determining the desired renderer - // type. - bool determining_renderer_type_; + HRESULT FillBuffer(); + void SaveSuggestedMimeType(LPCWSTR status_text); + void FireSugestedMimeType(IInternetProtocolSink* delegate); +}; - private: - DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap); +struct TransactionHooks { + void InstallHooks(); + void RevertHooks(); }; +DECLSPEC_SELECTANY struct TransactionHooks g_trans_hooks; + #endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ + |