Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: chrome_frame/protocol_sink_wrap.h

Issue 2620001: A new way of hooking internet protocols. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/bind_context_info.h ('k') | chrome_frame/protocol_sink_wrap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ 5 #ifndef CHROME_FRAME_PROTOCOL_SINK_WRAP_H_
6 #define CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ 6 #define CHROME_FRAME_PROTOCOL_SINK_WRAP_H_
7 7
8 #include <exdisp.h> 8 #include <exdisp.h>
9 #include <urlmon.h> 9 #include <urlmon.h>
10 #include <atlbase.h> 10 #include <atlbase.h>
11 #include <atlcom.h> 11 #include <atlcom.h>
12 12
13 #include <map> 13 #include <map>
14 #include <string> 14 #include <string>
15 15
16 #include "base/basictypes.h" 16 #include "base/basictypes.h"
17 #include "base/ref_counted.h" 17 #include "base/ref_counted.h"
18 #include "base/scoped_comptr_win.h" 18 #include "base/scoped_comptr_win.h"
19 #include "base/scoped_bstr_win.h"
19 #include "googleurl/src/gurl.h" 20 #include "googleurl/src/gurl.h"
20 #include "chrome_frame/chrome_frame_delegate.h" 21 #include "chrome_frame/chrome_frame_delegate.h"
21 #include "chrome_frame/ie8_types.h" 22 #include "chrome_frame/ie8_types.h"
22 #include "chrome_frame/utils.h" 23 #include "chrome_frame/utils.h"
23 #include "chrome_frame/vtable_patch_manager.h" 24 #include "chrome_frame/vtable_patch_manager.h"
24 25
25 // Typedefs for IInternetProtocol and related methods that we patch. 26 // Typedefs for IInternetProtocol and related methods that we patch.
26 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Start_Fn)( 27 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Start_Fn)(
27 IInternetProtocol* this_object, LPCWSTR url, 28 IInternetProtocol* this_object, LPCWSTR url,
28 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, 29 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info,
29 DWORD flags, HANDLE_PTR reserved); 30 DWORD flags, HANDLE_PTR reserved);
30 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Read_Fn)( 31 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Read_Fn)(
31 IInternetProtocol* this_object, void* buffer, ULONG size, 32 IInternetProtocol* this_object, void* buffer, ULONG size,
32 ULONG* size_read); 33 ULONG* size_read);
33 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_StartEx_Fn)( 34 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_StartEx_Fn)(
34 IInternetProtocolEx* this_object, IUri* uri, 35 IInternetProtocolEx* this_object, IUri* uri,
35 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, 36 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info,
36 DWORD flags, HANDLE_PTR reserved); 37 DWORD flags, HANDLE_PTR reserved);
37 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocolRoot_Continue_Fn)( 38 typedef HRESULT (STDMETHODCALLTYPE* InternetProtocolRoot_Continue_Fn)(
38 IInternetProtocolRoot* me, PROTOCOLDATA* data); 39 IInternetProtocolRoot* me, PROTOCOLDATA* data);
39 40
41
42 enum RendererType {
43 UNDETERMINED,
44 CHROME,
45 OTHER
46 };
47
48 class ProtData;
49
40 // A class to wrap protocol sink in IInternetProtocol::Start[Ex] for 50 // A class to wrap protocol sink in IInternetProtocol::Start[Ex] for
41 // HTTP and HTTPS protocols. 51 // HTTP and HTTPS protocols.
42 // 52 //
43 // This is an alternative to a mime filter and we have to do this in order 53 // This is an alternative to a mime filter and we have to do this in order
44 // to inspect initial portion of HTML for 'chrome' meta tag and report 54 // to inspect initial portion of HTML for 'chrome' meta tag and report
45 // a different mime type in that case. 55 // a different mime type in that case.
46 // 56 //
47 // We implement several documented interfaces 57 // We implement several documented interfaces
48 // supported by the original sink provided by urlmon. There are a few 58 // supported by the original sink provided by urlmon. There are a few
49 // undocumented interfaces that we have chosen not to implement 59 // undocumented interfaces that we have chosen not to implement
50 // but delegate simply the QI. 60 // but delegate simply the QI.
51 class ProtocolSinkWrap 61 class ProtocolSinkWrap
52 : public CComObjectRootEx<CComMultiThreadModel>, 62 : public CComObjectRootEx<CComMultiThreadModel>,
53 public IInternetProtocolSink, 63 public IInternetProtocolSink {
54 public IInternetBindInfoEx,
55 public IServiceProvider,
56 public IAuthenticate,
57 public IInternetProtocolEx,
58 public IInternetPriority,
59 public IWrappedProtocol,
60 // public IPreBindingSupport, // undocumented
61 // public ITransProtocolSink, // Undocumented
62 // public ITransactionInternal, // undocumented
63 public IUriContainer {
64 public: 64 public:
65 65
66 BEGIN_COM_MAP(ProtocolSinkWrap) 66 BEGIN_COM_MAP(ProtocolSinkWrap)
67 COM_INTERFACE_ENTRY(IInternetProtocolSink) 67 COM_INTERFACE_ENTRY(IInternetProtocolSink)
68 COM_INTERFACE_ENTRY(IInternetBindInfo)
69 COM_INTERFACE_ENTRY(IInternetBindInfoEx)
70 COM_INTERFACE_ENTRY(IServiceProvider)
71 COM_INTERFACE_ENTRY(IAuthenticate)
72 COM_INTERFACE_ENTRY(IInternetProtocolRoot)
73 COM_INTERFACE_ENTRY(IInternetProtocol)
74 COM_INTERFACE_ENTRY(IInternetProtocolEx)
75 COM_INTERFACE_ENTRY(IInternetPriority)
76 COM_INTERFACE_ENTRY(IWrappedProtocol)
77 COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(IUriContainer)
78 COM_INTERFACE_BLIND_DELEGATE() 68 COM_INTERFACE_BLIND_DELEGATE()
79 END_COM_MAP() 69 END_COM_MAP()
80 70
71 static ScopedComPtr<IInternetProtocolSink> CreateNewSink(
72 IInternetProtocolSink* sink, ProtData* prot_data);
73
74 // Apparently this has to be public, to satisfy COM_INTERFACE_BLIND_DELEGATE
75 IInternetProtocolSink* delegate() {
76 return delegate_;
77 }
78
79 protected:
81 ProtocolSinkWrap(); 80 ProtocolSinkWrap();
82 virtual ~ProtocolSinkWrap(); 81 ~ProtocolSinkWrap();
83 82
84 bool Initialize(IInternetProtocol* protocol, 83 private:
85 IInternetProtocolSink* original_sink, const wchar_t* url);
86
87 // VTable patches the IInternetProtocol and IIntenetProtocolEx interface.
88 // Returns true on success.
89 static bool PatchProtocolHandlers();
90
91 // Unpatches the IInternetProtocol and IInternetProtocolEx interfaces.
92 static void UnpatchProtocolHandlers();
93
94 // IInternetProtocol/Ex patches.
95 static STDMETHODIMP OnStart(InternetProtocol_Start_Fn orig_start,
96 IInternetProtocol* protocol, LPCWSTR url,
97 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info,
98 DWORD flags, HANDLE_PTR reserved);
99
100 static STDMETHODIMP OnStartEx(
101 InternetProtocol_StartEx_Fn orig_start_ex, IInternetProtocolEx* protocol,
102 IUri* uri, IInternetProtocolSink* prot_sink,
103 IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved);
104
105 static STDMETHODIMP OnRead(InternetProtocol_Read_Fn orig_read,
106 IInternetProtocol* protocol, void* buffer, ULONG size, ULONG* size_read);
107
108 // IInternetProtocolSink methods 84 // IInternetProtocolSink methods
109 STDMETHOD(Switch)(PROTOCOLDATA* protocol_data); 85 STDMETHOD(Switch)(PROTOCOLDATA* protocol_data);
110 STDMETHOD(ReportProgress)(ULONG status_code, LPCWSTR status_text); 86 STDMETHOD(ReportProgress)(ULONG status_code, LPCWSTR status_text);
111 STDMETHOD(ReportData)(DWORD flags, ULONG progress, ULONG max_progress); 87 STDMETHOD(ReportData)(DWORD flags, ULONG progress, ULONG max_progress);
112 STDMETHOD(ReportResult)(HRESULT result, DWORD error, LPCWSTR result_text); 88 STDMETHOD(ReportResult)(HRESULT result, DWORD error, LPCWSTR result_text);
113 89
114 // IInternetBindInfoEx 90 // Remember original sink
115 STDMETHOD(GetBindInfo)(DWORD* flags, BINDINFO* bind_info); 91 ScopedComPtr<IInternetProtocolSink> delegate_;
116 STDMETHOD(GetBindString)(ULONG string_type, LPOLESTR* string_array, 92 scoped_refptr<ProtData> prot_data_;
117 ULONG array_size, ULONG* size_returned); 93 DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap);
118 STDMETHOD(GetBindInfoEx)(DWORD *flags, BINDINFO* bind_info, 94 };
119 DWORD* bindf2, DWORD *reserved);
120 95
121 // IServiceProvider 96 class ProtData : public base::RefCounted<ProtData> {
122 STDMETHOD(QueryService)(REFGUID service_guid, REFIID riid, void** service); 97 public:
98 ProtData(IInternetProtocol* protocol, InternetProtocol_Read_Fn read_fun,
99 const wchar_t* url);
100 ~ProtData();
101 HRESULT Read(void* buffer, ULONG size, ULONG* size_read);
102 HRESULT ReportProgress(IInternetProtocolSink* delegate,
103 ULONG status_code,
104 LPCWSTR status_text);
105 HRESULT ReportData(IInternetProtocolSink* delegate,
106 DWORD flags, ULONG progress, ULONG max_progress);
107 HRESULT ReportResult(IInternetProtocolSink* delegate, HRESULT result,
108 DWORD error, LPCWSTR result_text);
109 void UpdateUrl(const wchar_t* url);
110 static scoped_refptr<ProtData> DataFromProtocol(IInternetProtocol* protocol);
123 111
124 // IAuthenticate 112 RendererType renderer_type() {
125 STDMETHOD(Authenticate)(HWND* window, LPWSTR* user_name, LPWSTR* password);
126
127 // IInternetProtocolEx
128 STDMETHOD(Start)(LPCWSTR url, IInternetProtocolSink *protocol_sink,
129 IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved);
130 STDMETHOD(Continue)(PROTOCOLDATA* protocol_data);
131 STDMETHOD(Abort)(HRESULT reason, DWORD options);
132 STDMETHOD(Terminate)(DWORD options);
133 STDMETHOD(Suspend)();
134 STDMETHOD(Resume)();
135 STDMETHOD(Read)(void *buffer, ULONG size, ULONG* size_read);
136 STDMETHOD(Seek)(LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER* new_pos);
137 STDMETHOD(LockRequest)(DWORD options);
138 STDMETHOD(UnlockRequest)();
139 STDMETHOD(StartEx)(IUri* uri, IInternetProtocolSink* protocol_sink,
140 IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved);
141
142 // IInternetPriority
143 STDMETHOD(SetPriority)(LONG priority);
144 STDMETHOD(GetPriority)(LONG* priority);
145
146 // IWrappedProtocol
147 STDMETHOD(GetWrapperCode)(LONG *code, DWORD_PTR reserved);
148
149 // public IUriContainer
150 STDMETHOD(GetIUri)(IUri** uri);
151
152 // IPreBindingSupport, // undocumented
153 // ITransProtocolSink, // Undocumented
154 // ITransactionInternal, // undocumented
155
156 IInternetProtocolSink* delegate() const {
157 return delegate_;
158 }
159
160 protected:
161 enum RendererType {
162 UNDETERMINED,
163 CHROME,
164 OTHER
165 };
166
167 typedef std::map<IInternetProtocol*, ProtocolSinkWrap*> ProtocolSinkMap;
168 static const int kMaxContentSniffLength = 1024;
169
170 static scoped_refptr<ProtocolSinkWrap> InstanceFromProtocol(
171 IInternetProtocol* protocol);
172 static ScopedComPtr<IInternetProtocolSink> MaybeWrapSink(
173 IInternetProtocol* protocol, IInternetProtocolSink* prot_sink,
174 const wchar_t* url);
175
176 void DetermineRendererType();
177
178 HRESULT OnReadImpl(void* buffer, ULONG size, ULONG* size_read,
179 InternetProtocol_Read_Fn orig_read);
180
181 // This function determines whether the current request should be handled
182 // by Chrome. If yes it reports the mime type as application/chromepage,
183 // which ensures that the ChromeFrame is instantiated for handling this
184 // request.
185 // Returns S_OK on success.
186 HRESULT CheckAndReportChromeMimeTypeForRequest();
187
188 bool is_undetermined() const {
189 return (UNDETERMINED == renderer_type_);
190 }
191 RendererType renderer_type() const {
192 return renderer_type_; 113 return renderer_type_;
193 } 114 }
194 115
195 // Creates an instance of the specified protocol handler and returns the 116 private:
196 // IInternetProtocol interface pointer. 117 typedef std::map<IInternetProtocol*, ProtData*> ProtocolDataMap;
197 // Returns S_OK on success. 118 static ProtocolDataMap datamap_;
198 static HRESULT CreateProtocolHandlerInstance(const CLSID& clsid, 119 static Lock datamap_lock_;
199 IInternetProtocol** protocol);
200 120
201 // Helper function for patching the VTable of the IInternetProtocol 121 // Url we are retrieving. Used for IsOptInUrl() only.
202 // interface. It instantiates the object identified by the protocol_clsid 122 std::wstring url_;
203 // parameter and patches its VTable. 123 // Our gate to IInternetProtocol::Read()
204 // Returns S_OK on success. 124 IInternetProtocol* protocol_;
205 static HRESULT PatchProtocolMethods( 125 InternetProtocol_Read_Fn read_fun_;
206 const CLSID& protocol_clsid,
207 vtable_patch::MethodPatchInfo* protocol_patch_info,
208 vtable_patch::MethodPatchInfo* protocol_ex_patch_info);
209 126
210 // WARNING: Don't use GURL variables here. Please see 127 // What BINDSTATUS_MIMETYPEAVAILABLE and Co. tells us.
211 // http://b/issue?id=2102171 for details. 128 ScopedBstr suggested_mime_type_;
129 // At least one of the following has been received:
130 // BINDSTATUS_MIMETYPEAVAILABLE,
131 // MIMESTATUS_VERIFIEDMIMETYPEAVAILABLE
132 // BINDSTATUS_SERVER_MIMETYPEAVAILABLE
133 bool has_suggested_mime_type_;
134 // BINDSTATUS_SERVER_MIMETYPEAVAILABLE received, so we shall fire one.
135 bool has_server_mime_type_;
212 136
213 // Remember original sink 137 // Did we received ReportData()
214 ScopedComPtr<IInternetProtocolSink> delegate_; 138 bool report_data_received_;
215
216 // Cannot take a reference on the protocol.
217 IInternetProtocol* protocol_;
218 RendererType renderer_type_; 139 RendererType renderer_type_;
219 140
220 // Buffer for accumulated data including 1 extra for NULL-terminator 141 // Buffer for accumulated data including 1 extra for NULL-terminator
142 static const size_t kMaxContentSniffLength = 2 * 1024;
221 char buffer_[kMaxContentSniffLength + 1]; 143 char buffer_[kMaxContentSniffLength + 1];
222 unsigned long buffer_size_; // NOLINT 144 unsigned long buffer_size_; // NOLINT
223 unsigned long buffer_pos_; // NOLINT 145 unsigned long buffer_pos_; // NOLINT
224 146
225 // Accumulated result 147 HRESULT FillBuffer();
226 bool is_saved_result_; 148 void SaveSuggestedMimeType(LPCWSTR status_text);
227 HRESULT result_code_; 149 void FireSugestedMimeType(IInternetProtocolSink* delegate);
228 DWORD result_error_;
229 std::wstring result_text_;
230 // For tracking re-entrency and preventing duplicate Read()s from
231 // distorting the outcome of ReportData.
232 int report_data_recursiveness_;
233
234 static ProtocolSinkMap sink_map_;
235 // TODO(joshia): Replace with Lock
236 static CComAutoCriticalSection sink_map_lock_;
237
238 std::wstring url_;
239
240 // Set to true if we are in the context of determining the desired renderer
241 // type.
242 bool determining_renderer_type_;
243
244 private:
245 DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap);
246 }; 150 };
247 151
152 struct TransactionHooks {
153 void InstallHooks();
154 void RevertHooks();
155 };
156
157 DECLSPEC_SELECTANY struct TransactionHooks g_trans_hooks;
158
248 #endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ 159 #endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_
160
OLDNEW
« no previous file with comments | « chrome_frame/bind_context_info.h ('k') | chrome_frame/protocol_sink_wrap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698