summaryrefslogtreecommitdiffstats
path: root/chrome_frame/protocol_sink_wrap.h
diff options
context:
space:
mode:
authorstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 16:54:12 +0000
committerstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 16:54:12 +0000
commitce2b9f923c23700d24658b5118ab9c1d2f330d8b (patch)
treebdd559fc120cc9b5e5111a5c53efc4e3e0184466 /chrome_frame/protocol_sink_wrap.h
parent78c7e2c68da0079869252bb464f4633373e5d067 (diff)
downloadchromium_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.h238
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_
+