blob: d201a993fb62c9279cf1e2733a325d01fee0f9af [file] [log] [blame]
[email protected]6e58a952011-01-12 19:28:501// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]f7817822009-09-24 05:11:582// 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>
[email protected]3f55e872009-10-17 04:48:3712
[email protected]f7817822009-09-24 05:11:5813#include <map>
14#include <string>
15
16#include "base/basictypes.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
[email protected]965722ff2010-10-20 15:50:3018#include "base/win/scoped_comptr.h"
19#include "base/win/scoped_bstr.h"
[email protected]f7817822009-09-24 05:11:5820#include "googleurl/src/gurl.h"
[email protected]921a31d2009-12-23 19:43:1221#include "chrome_frame/chrome_frame_delegate.h"
[email protected]aaf124502010-07-17 04:02:5822#include "chrome_frame/http_negotiate.h"
[email protected]f7817822009-09-24 05:11:5823#include "chrome_frame/ie8_types.h"
[email protected]3f55e872009-10-17 04:48:3724#include "chrome_frame/utils.h"
[email protected]bc88e9d72009-09-25 16:04:4325#include "chrome_frame/vtable_patch_manager.h"
[email protected]f7817822009-09-24 05:11:5826
27// Typedefs for IInternetProtocol and related methods that we patch.
28typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Start_Fn)(
29 IInternetProtocol* this_object, LPCWSTR url,
30 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info,
31 DWORD flags, HANDLE_PTR reserved);
32typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Read_Fn)(
33 IInternetProtocol* this_object, void* buffer, ULONG size,
34 ULONG* size_read);
35typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_StartEx_Fn)(
36 IInternetProtocolEx* this_object, IUri* uri,
37 IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info,
38 DWORD flags, HANDLE_PTR reserved);
[email protected]c4e45b32010-07-28 21:15:1539typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_LockRequest_Fn)(
40 IInternetProtocol* this_object, DWORD options);
41typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_UnlockRequest_Fn)(
42 IInternetProtocol* this_object);
[email protected]f7817822009-09-24 05:11:5843
[email protected]ce2b9f922010-06-09 16:54:1244
[email protected]ce2b9f922010-06-09 16:54:1245class ProtData;
46
[email protected]f7817822009-09-24 05:11:5847// A class to wrap protocol sink in IInternetProtocol::Start[Ex] for
48// HTTP and HTTPS protocols.
49//
50// This is an alternative to a mime filter and we have to do this in order
51// to inspect initial portion of HTML for 'chrome' meta tag and report
52// a different mime type in that case.
53//
54// We implement several documented interfaces
55// supported by the original sink provided by urlmon. There are a few
56// undocumented interfaces that we have chosen not to implement
57// but delegate simply the QI.
58class ProtocolSinkWrap
59 : public CComObjectRootEx<CComMultiThreadModel>,
[email protected]ce2b9f922010-06-09 16:54:1260 public IInternetProtocolSink {
[email protected]f7817822009-09-24 05:11:5861 public:
62
[email protected]f7817822009-09-24 05:11:5863BEGIN_COM_MAP(ProtocolSinkWrap)
64 COM_INTERFACE_ENTRY(IInternetProtocolSink)
[email protected]3f55e872009-10-17 04:48:3765 COM_INTERFACE_BLIND_DELEGATE()
[email protected]f7817822009-09-24 05:11:5866END_COM_MAP()
67
[email protected]965722ff2010-10-20 15:50:3068 static base::win::ScopedComPtr<IInternetProtocolSink> CreateNewSink(
[email protected]ce2b9f922010-06-09 16:54:1269 IInternetProtocolSink* sink, ProtData* prot_data);
70
[email protected]6e58a952011-01-12 19:28:5071 // Enables or disables activation of Chrome Frame via the X-UA-Compatible
72 // header or meta tag. The tag/header is respected by default.
73 static void set_ignore_xua(bool ignore_xua) { ignore_xua_ = ignore_xua; }
74 static bool ignore_xua() { return ignore_xua_; }
75
[email protected]ce2b9f922010-06-09 16:54:1276 // Apparently this has to be public, to satisfy COM_INTERFACE_BLIND_DELEGATE
77 IInternetProtocolSink* delegate() {
78 return delegate_;
79 }
80
81 protected:
[email protected]f7817822009-09-24 05:11:5882 ProtocolSinkWrap();
[email protected]ce2b9f922010-06-09 16:54:1283 ~ProtocolSinkWrap();
[email protected]f7817822009-09-24 05:11:5884
[email protected]ce2b9f922010-06-09 16:54:1285 private:
[email protected]6e58a952011-01-12 19:28:5086 static bool ignore_xua_;
87
[email protected]f7817822009-09-24 05:11:5888 // IInternetProtocolSink methods
89 STDMETHOD(Switch)(PROTOCOLDATA* protocol_data);
90 STDMETHOD(ReportProgress)(ULONG status_code, LPCWSTR status_text);
91 STDMETHOD(ReportData)(DWORD flags, ULONG progress, ULONG max_progress);
92 STDMETHOD(ReportResult)(HRESULT result, DWORD error, LPCWSTR result_text);
93
[email protected]ce2b9f922010-06-09 16:54:1294 // Remember original sink
[email protected]965722ff2010-10-20 15:50:3095 base::win::ScopedComPtr<IInternetProtocolSink> delegate_;
96 base::win::ScopedComPtr<IServiceProvider> delegate_service_provider_;
[email protected]ce2b9f922010-06-09 16:54:1297 scoped_refptr<ProtData> prot_data_;
98 DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap);
99};
[email protected]f7817822009-09-24 05:11:58100
[email protected]ce2b9f922010-06-09 16:54:12101class ProtData : public base::RefCounted<ProtData> {
102 public:
103 ProtData(IInternetProtocol* protocol, InternetProtocol_Read_Fn read_fun,
104 const wchar_t* url);
105 ~ProtData();
106 HRESULT Read(void* buffer, ULONG size, ULONG* size_read);
107 HRESULT ReportProgress(IInternetProtocolSink* delegate,
108 ULONG status_code,
109 LPCWSTR status_text);
110 HRESULT ReportData(IInternetProtocolSink* delegate,
111 DWORD flags, ULONG progress, ULONG max_progress);
112 HRESULT ReportResult(IInternetProtocolSink* delegate, HRESULT result,
113 DWORD error, LPCWSTR result_text);
114 void UpdateUrl(const wchar_t* url);
115 static scoped_refptr<ProtData> DataFromProtocol(IInternetProtocol* protocol);
[email protected]f7817822009-09-24 05:11:58116
[email protected]ce2b9f922010-06-09 16:54:12117 RendererType renderer_type() {
[email protected]f7817822009-09-24 05:11:58118 return renderer_type_;
119 }
120
[email protected]aaf124502010-07-17 04:02:58121 // Valid only if renderer_type_ is CHROME.
122 const std::string& referrer() const {
123 return referrer_;
124 }
125
[email protected]c4e45b32010-07-28 21:15:15126 bool is_attach_external_tab_request() const {
127 return read_fun_ == NULL;
128 }
129
[email protected]5aef0fa2010-08-02 17:10:57130 // Removes the mapping between the protocol and the ProtData.
131 void Invalidate();
132
[email protected]4f45d4582011-02-22 23:27:27133 const std::wstring& url() const {
134 return url_;
135 }
136
[email protected]ce2b9f922010-06-09 16:54:12137 private:
138 typedef std::map<IInternetProtocol*, ProtData*> ProtocolDataMap;
139 static ProtocolDataMap datamap_;
[email protected]68c34032011-01-21 05:30:19140 static base::Lock datamap_lock_;
[email protected]bc88e9d72009-09-25 16:04:43141
[email protected]d8e13512010-09-22 17:02:58142 // Url we are retrieving. Used for RendererTypeForUrl() only.
[email protected]ce2b9f922010-06-09 16:54:12143 std::wstring url_;
[email protected]aaf124502010-07-17 04:02:58144 // HTTP "Referrer" header if we detect are going to switch.
145 // We have to save and pass it to Chrome, so scripts can read it via DOM.
146 std::string referrer_;
147
[email protected]ce2b9f922010-06-09 16:54:12148 // Our gate to IInternetProtocol::Read()
[email protected]f7817822009-09-24 05:11:58149 IInternetProtocol* protocol_;
[email protected]ce2b9f922010-06-09 16:54:12150 InternetProtocol_Read_Fn read_fun_;
151
152 // What BINDSTATUS_MIMETYPEAVAILABLE and Co. tells us.
[email protected]965722ff2010-10-20 15:50:30153 base::win::ScopedBstr suggested_mime_type_;
[email protected]ce2b9f922010-06-09 16:54:12154 // At least one of the following has been received:
155 // BINDSTATUS_MIMETYPEAVAILABLE,
156 // MIMESTATUS_VERIFIEDMIMETYPEAVAILABLE
157 // BINDSTATUS_SERVER_MIMETYPEAVAILABLE
158 bool has_suggested_mime_type_;
159 // BINDSTATUS_SERVER_MIMETYPEAVAILABLE received, so we shall fire one.
160 bool has_server_mime_type_;
161
[email protected]f7817822009-09-24 05:11:58162 RendererType renderer_type_;
163
164 // Buffer for accumulated data including 1 extra for NULL-terminator
[email protected]ce2b9f922010-06-09 16:54:12165 static const size_t kMaxContentSniffLength = 2 * 1024;
[email protected]f7817822009-09-24 05:11:58166 char buffer_[kMaxContentSniffLength + 1];
[email protected]3f55e872009-10-17 04:48:37167 unsigned long buffer_size_; // NOLINT
168 unsigned long buffer_pos_; // NOLINT
[email protected]f7817822009-09-24 05:11:58169
[email protected]ce2b9f922010-06-09 16:54:12170 HRESULT FillBuffer();
171 void SaveSuggestedMimeType(LPCWSTR status_text);
[email protected]7ab36c4f2010-08-11 03:47:43172 void FireSuggestedMimeType(IInternetProtocolSink* delegate);
[email protected]aaf124502010-07-17 04:02:58173 void SaveReferrer(IInternetProtocolSink* delegate);
[email protected]f7817822009-09-24 05:11:58174};
175
[email protected]ce2b9f922010-06-09 16:54:12176struct TransactionHooks {
177 void InstallHooks();
178 void RevertHooks();
179};
180
181DECLSPEC_SELECTANY struct TransactionHooks g_trans_hooks;
182
[email protected]f7817822009-09-24 05:11:58183#endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_