| Index: chrome_frame/protocol_sink_wrap.h
|
| ===================================================================
|
| --- chrome_frame/protocol_sink_wrap.h (revision 48838)
|
| +++ chrome_frame/protocol_sink_wrap.h (working copy)
|
| @@ -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* 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 @@
|
| // 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();
|
| + static ScopedComPtr<IInternetProtocolSink> CreateNewSink(
|
| + IInternetProtocolSink* sink, ProtData* prot_data);
|
|
|
| - bool Initialize(IInternetProtocol* protocol,
|
| - IInternetProtocolSink* original_sink, const wchar_t* url);
|
| + // Apparently this has to be public, to satisfy COM_INTERFACE_BLIND_DELEGATE
|
| + IInternetProtocolSink* delegate() {
|
| + return delegate_;
|
| + }
|
|
|
| - // VTable patches the IInternetProtocol and IIntenetProtocolEx interface.
|
| - // Returns true on success.
|
| - static bool PatchProtocolHandlers();
|
| + protected:
|
| + ProtocolSinkWrap();
|
| + ~ProtocolSinkWrap();
|
|
|
| - // Unpatches the IInternetProtocol and IInternetProtocolEx interfaces.
|
| - static void UnpatchProtocolHandlers();
|
| -
|
| - // 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);
|
| -
|
| - static STDMETHODIMP OnRead(InternetProtocol_Read_Fn orig_read,
|
| - IInternetProtocol* protocol, void* buffer, ULONG size, ULONG* size_read);
|
| -
|
| + 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);
|
| + // Remember original sink
|
| + ScopedComPtr<IInternetProtocolSink> delegate_;
|
| + scoped_refptr<ProtData> prot_data_;
|
| + DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap);
|
| +};
|
|
|
| - // IServiceProvider
|
| - STDMETHOD(QueryService)(REFGUID service_guid, REFIID riid, void** service);
|
| +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);
|
|
|
| - // 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_;
|
| - }
|
| -
|
| - 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 {
|
| + 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);
|
| + private:
|
| + typedef std::map<IInternetProtocol*, ProtData*> ProtocolDataMap;
|
| + static ProtocolDataMap datamap_;
|
| + static Lock datamap_lock_;
|
|
|
| - // 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);
|
| + // Url we are retrieving. Used for IsOptInUrl() only.
|
| + std::wstring url_;
|
| + // Our gate to IInternetProtocol::Read()
|
| + IInternetProtocol* protocol_;
|
| + InternetProtocol_Read_Fn read_fun_;
|
|
|
| - // WARNING: Don't use GURL variables here. Please see
|
| - // http://b/issue?id=2102171 for details.
|
| + // 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_;
|
|
|
| - // Remember original sink
|
| - ScopedComPtr<IInternetProtocolSink> delegate_;
|
| -
|
| - // Cannot take a reference on the protocol.
|
| - IInternetProtocol* protocol_;
|
| + // 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_;
|
| + HRESULT FillBuffer();
|
| + void SaveSuggestedMimeType(LPCWSTR status_text);
|
| + void FireSugestedMimeType(IInternetProtocolSink* delegate);
|
| +};
|
|
|
| - 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_;
|
| -
|
| - 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_
|
| +
|
|
|