Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginWbPassThrough.cpp

Issue 6299667012780032: Issues #696,1231,1264,1265 - Improve handling in PassthroughApp (Closed)
Patch Set: Get rid of yoda style and rename blockedByABPPageSize local var Created Sept. 22, 2014, 4:14 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/plugin/PluginWbPassThrough.h ('k') | src/plugin/SinkPolicy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "PluginStdAfx.h" 1 #include "PluginStdAfx.h"
2 2
3 #include "PluginWbPassThrough.h" 3 #include "PluginWbPassThrough.h"
4 #include "PluginClient.h" 4 #include "PluginClient.h"
5 #include "PluginClientFactory.h" 5 #include "PluginClientFactory.h"
6 #ifdef SUPPORT_FILTER 6 #ifdef SUPPORT_FILTER
7 #include "PluginFilter.h" 7 #include "PluginFilter.h"
8 #endif 8 #endif
9 #include "PluginSettings.h" 9 #include "PluginSettings.h"
10 #include "PluginClass.h" 10 #include "PluginClass.h"
11 #include "PluginSystem.h" 11 #include "PluginSystem.h"
12 12 #include <WinInet.h>
13 #include "wtypes.h" 13 #include "wtypes.h"
14 14
15 EXTERN_C IMAGE_DOS_HEADER __ImageBase;
16
17 namespace 15 namespace
18 { 16 {
19 std::string g_myPageBlocked = "<!DOCTYPE html>" 17 std::string g_blockedByABPPage = "<!DOCTYPE html>"
20 "<html>" 18 "<html>"
21 "<body>" 19 "<body>"
22 "<!-- blocked by AdblockPlus -->" 20 "<!-- blocked by AdblockPlus -->"
23 "</body>" 21 "</body>"
24 "</html>"; 22 "</html>";
25 } 23 }
26 24
27 int WBPassthruSink::GetContentTypeFromMimeType(CString mimeType) 25 WBPassthruSink::WBPassthruSink()
26 : m_currentPositionOfSentPage(0)
27 , m_contentType(CFilter::EContentType::contentTypeAny)
28 , m_blockedInTransaction(false)
29 {
30 }
31
32 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType)
28 { 33 {
29 if (mimeType.Find(L"image/") >= 0) 34 if (mimeType.Find(L"image/") >= 0)
30 { 35 {
31 return CFilter::contentTypeImage; 36 return CFilter::contentTypeImage;
32 } 37 }
33 if (mimeType.Find(L"text/css") >= 0) 38 if (mimeType.Find(L"text/css") >= 0)
34 { 39 {
35 return CFilter::contentTypeStyleSheet; 40 return CFilter::contentTypeStyleSheet;
36 } 41 }
37 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0)) 42 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0))
(...skipping 10 matching lines...) Expand all
48 } 53 }
49 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example 54 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example
50 if (mimeType.Find(L"xml") >= 0) 55 if (mimeType.Find(L"xml") >= 0)
51 { 56 {
52 return CFilter::contentTypeXmlHttpRequest; 57 return CFilter::contentTypeXmlHttpRequest;
53 } 58 }
54 59
55 return CFilter::contentTypeAny; 60 return CFilter::contentTypeAny;
56 } 61 }
57 62
58 int WBPassthruSink::GetContentTypeFromURL(CString src) 63 int WBPassthruSink::GetContentTypeFromURL(const CString& src)
59 { 64 {
60 CString srcExt = src; 65 CString srcExt = src;
61 66
62 int pos = 0; 67 int pos = 0;
63 if ((pos = src.Find('?')) > 0) 68 if ((pos = src.Find('?')) > 0)
64 { 69 {
65 srcExt = src.Left(pos); 70 srcExt = src.Left(pos);
66 } 71 }
67 72
68 int lastDotIndex = srcExt.ReverseFind('.'); 73 int lastDotIndex = srcExt.ReverseFind('.');
(...skipping 17 matching lines...) Expand all
86 return CFilter::contentTypeXmlHttpRequest; 91 return CFilter::contentTypeXmlHttpRequest;
87 } 92 }
88 else if (ext == L".swf") 93 else if (ext == L".swf")
89 { 94 {
90 return CFilter::contentTypeObject; 95 return CFilter::contentTypeObject;
91 } 96 }
92 else if (ext == L".jsp" || ext == L".php" || ext == L".html") 97 else if (ext == L".jsp" || ext == L".php" || ext == L".html")
93 { 98 {
94 return CFilter::contentTypeSubdocument; 99 return CFilter::contentTypeSubdocument;
95 } 100 }
96 else 101 return CFilter::contentTypeAny;
97 {
98 return CFilter::contentTypeAny & ~CFilter::contentTypeSubdocument;
99 }
100
101 } 102 }
102 103
103 int WBPassthruSink::GetContentType(CString mimeType, CString domain, CString src ) 104 int WBPassthruSink::GetContentType(const CString& mimeType, const CString& domai n, const CString& src)
104 { 105 {
105 // No referer or mime type 106 // No referer or mime type
106 // BINDSTRING_XDR_ORIGIN works only for IE v8+ 107 // BINDSTRING_XDR_ORIGIN works only for IE v8+
107 if (mimeType.IsEmpty() && domain.IsEmpty() && CPluginClient::GetInstance()->Ge tIEVersion() >= 8) 108 if (mimeType.IsEmpty() && domain.IsEmpty() && CPluginClient::GetInstance()->Ge tIEVersion() >= 8)
108 { 109 {
109 return CFilter::contentTypeXmlHttpRequest; 110 return CFilter::contentTypeXmlHttpRequest;
110 } 111 }
111 int contentType = GetContentTypeFromMimeType(mimeType); 112 int contentType = GetContentTypeFromMimeType(mimeType);
112 if (contentType == CFilter::contentTypeAny) 113 if (contentType == CFilter::contentTypeAny)
113 { 114 {
114 contentType = GetContentTypeFromURL(src); 115 contentType = GetContentTypeFromURL(src);
115 } 116 }
116 return contentType; 117 return contentType;
117 } 118 }
118 119
119 //////////////////////////////////////////////////////////////////////////////// //////// 120 //////////////////////////////////////////////////////////////////////////////// ////////
120 //WBPassthruSink 121 //WBPassthruSink
121 //Monitor and/or cancel every request and responde 122 //Monitor and/or cancel every request and responde
122 //WB makes, including images, sounds, scripts, etc 123 //WB makes, including images, sounds, scripts, etc
123 //////////////////////////////////////////////////////////////////////////////// //////// 124 //////////////////////////////////////////////////////////////////////////////// ////////
124 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, 125 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k,
125 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, 126 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved,
126 IInternetProtocol* pTargetProtocol, bool& handle d) 127 IInternetProtocol* pTargetProtocol, bool& handle d)
127 { 128 {
128 m_pTargetProtocol = pTargetProtocol; 129 m_pTargetProtocol = pTargetProtocol;
129 bool isBlocked = false; 130 bool isBlocked = false;
130 m_currentPositionOfSentPage = 0; 131 CString src = szUrl;
131 CString src;
132 src.Append(szUrl);
133 DEBUG_GENERAL(src); 132 DEBUG_GENERAL(src);
134 CPluginClient::UnescapeUrl(src); 133 CPluginClient::UnescapeUrl(src);
135 134
136 CString boundDomain; 135 // call the impl of the base class as soon as possible because it initializes the base class
136 // members, used by this method. It queries for the required interfaces.
137 HRESULT hr = BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwRese rved, pTargetProtocol);
138 if (FAILED(hr))
139 {
140 return hr;
141 }
142
137 CString mimeType; 143 CString mimeType;
138 LPOLESTR mime[10];
139 if (pOIBindInfo) 144 if (pOIBindInfo)
140 { 145 {
141 ULONG resLen = 0; 146 ULONG resLen = 0;
142 147
143 // Apparently IE will report random mime type if there's more then 1 in the list. 148 // Apparently IE will report random mime type if there's more then 1 in the list.
144 // So we get the whole list and just use the first one (top priority one) 149 // So we get the whole list and just use the first one (top priority one)
150 LPOLESTR mime[10];
145 pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, mime, 10, &resLen); 151 pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, mime, 10, &resLen);
146 if (mime && resLen > 0) 152 if (mime && resLen > 0)
147 { 153 {
148 mimeType.SetString(mime[0]); 154 mimeType.SetString(mime[0]);
149 } 155 }
150 LPOLESTR bindToObject = 0; 156 LPOLESTR bindString = nullptr;
151 pOIBindInfo->GetBindString(BINDSTRING_FLAG_BIND_TO_OBJECT, &bindToObject, 1, &resLen); 157 pOIBindInfo->GetBindString(BINDSTRING_FLAG_BIND_TO_OBJECT, &bindString, 1, & resLen);
152 LPOLESTR domainRetrieved = 0; 158 LPOLESTR domainRetrieved = nullptr;
153 if (resLen == 0 || wcscmp(bindToObject, L"FALSE") == 0) 159 if (resLen == 0 || wcscmp(bindString, L"FALSE") == 0)
154 { 160 {
155 HRESULT hr = pOIBindInfo->GetBindString(BINDSTRING_XDR_ORIGIN, &domainRetr ieved, 1, &resLen); 161 HRESULT hr = pOIBindInfo->GetBindString(BINDSTRING_XDR_ORIGIN, &domainRetr ieved, 1, &resLen);
156
157 if ((hr == S_OK) && domainRetrieved && (resLen > 0)) 162 if ((hr == S_OK) && domainRetrieved && (resLen > 0))
158 { 163 {
159 boundDomain.SetString(domainRetrieved); 164 m_boundDomain = domainRetrieved;
160 } 165 }
161 } 166 }
167 // We can obtain IBindCtx* here, but IEnumString obtained via IBindCtx::Enum ObjectParam
168 // does not return any parameter, so it's useless.
162 } 169 }
163 170
164 CString cookie; 171 CString cookie;
165 ULONG len1 = 2048; 172 ULONG len1 = 2048;
166 ULONG len2 = 2048; 173 ULONG len2 = 2048;
167 174
168 #ifdef SUPPORT_FILTER 175 #ifdef SUPPORT_FILTER
169 int contentType = CFilter::contentTypeAny;
170
171 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); 176 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
172 CPluginClient* client = CPluginClient::GetInstance(); 177 CPluginClient* client = CPluginClient::GetInstance();
173 178
174
175 if (tab && client) 179 if (tab && client)
176 { 180 {
177 CString documentUrl = tab->GetDocumentUrl(); 181 CString documentUrl = tab->GetDocumentUrl();
178 // Page is identical to document => don't block 182 // Page is identical to document => don't block
179 if (documentUrl == src) 183 if (documentUrl == src)
180 { 184 {
181 // fall through 185 // fall through
182 } 186 }
183 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl))) 187 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl)))
184 { 188 {
185 boundDomain = tab->GetDocumentUrl(); 189 m_boundDomain = tab->GetDocumentUrl();
186 190 m_contentType = CFilter::contentTypeAny;
187 contentType = CFilter::contentTypeAny;
188
189 #ifdef SUPPORT_FRAME_CACHING 191 #ifdef SUPPORT_FRAME_CACHING
190 if ((tab != 0) && (tab->IsFrameCached(src))) 192 if (tab != nullptr && tab->IsFrameCached(src))
191 { 193 {
192 contentType = CFilter::contentTypeSubdocument; 194 m_contentType = CFilter::contentTypeSubdocument;
193 } 195 }
194 else 196 else
195 #endif // SUPPORT_FRAME_CACHING 197 #endif // SUPPORT_FRAME_CACHING
196 contentType = GetContentType(mimeType, boundDomain, src);
197 if (client->ShouldBlock(src, contentType, boundDomain, true))
198 { 198 {
199 isBlocked = true; 199 m_contentType = GetContentType(mimeType, m_boundDomain, src);
200
201 DEBUG_BLOCKER("Blocker::Blocking Http-request:" + src);
202 } 200 }
203 } 201 }
204 if (!isBlocked)
205 {
206 DEBUG_BLOCKER("Blocker::Ignoring Http-request:" + src)
207 }
208 } 202 }
209 203
204 if (tab == nullptr)
205 {
206 m_contentType = GetContentType(mimeType, m_boundDomain, src);
207 }
210 208
211 if (tab == NULL)
212 { 209 {
213 contentType = GetContentType(mimeType, boundDomain, src); 210 // Here is the heuristic which detects the requests issued by Flash.ocx.
214 if (client->ShouldBlock(src, contentType, boundDomain, true)) 211 // It turned out that the implementation from ''Flash.ocx'' (tested version is 15.0.0.152)
212 // returns quite minimal configuration in comparison with the implementation from Microsofts'
213 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often i ncludes something
214 // else.
215 ATL::CComPtr<IBindStatusCallback> bscb;
216 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb)
215 { 217 {
216 isBlocked = true; 218 DWORD grfBINDF = 0;
219 BINDINFO bindInfo = {};
220 bindInfo.cbSize = sizeof(bindInfo);
221 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo))
222 && (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF
223 && (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindInfo.dwOptions
224 )
225 {
226 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest;
227 }
217 } 228 }
218 } 229 }
219 230
220 #ifdef _DEBUG 231 // The descision about EContentType::contentTypeAny is made later in
221 CString type; 232 // WBPassthruSink::BeginningTransaction. Sometimes here we cannot detect the r equest type, but
233 // in WBPassthruSink::BeginningTransaction the header Accept is available whic h allows to
234 // obtain the "request type" in our terminology.
235 if (nullptr != client
236 && CFilter::EContentType::contentTypeAny != m_contentType
237 && client->ShouldBlock(src, m_contentType, m_boundDomain, true))
238 {
239 isBlocked = true;
240 }
222 241
223 if (contentType == CFilter::contentTypeDocument) type = "DOCUMENT"; 242 // For IE6 and earlier there is iframe back button issue, so avoid it.
224 else if (contentType == CFilter::contentTypeObject) type = "OBJECT"; 243 if (isBlocked && client->GetIEVersion() > 6)
225 else if (contentType == CFilter::contentTypeImage) type = "IMAGE";
226 else if (contentType == CFilter::contentTypeScript) type = "SCRIPT";
227 else if (contentType == CFilter::contentTypeOther) type = "OTHER";
228 else if (contentType == CFilter::contentTypeUnknown) type = "OTHER";
229 else if (contentType == CFilter::contentTypeSubdocument) type = "SUBDOCUMENT";
230 else if (contentType == CFilter::contentTypeStyleSheet) type = "STYLESHEET";
231 else type = "OTHER";
232
233 if (isBlocked)
234 { 244 {
235 CPluginDebug::DebugResultBlocking(type, src, boundDomain); 245 handled = true;
236 } 246 if (CFilter::EContentType::contentTypeImage == m_contentType)
237 else
238 {
239 CPluginDebug::DebugResultIgnoring(type, src, boundDomain);
240 }
241 #endif
242
243 //Fixes the iframe back button issue
244 if (client->GetIEVersion() > 6)
245 {
246 if (contentType == CFilter::contentTypeImage && isBlocked)
247 { 247 {
248 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
249 handled = true;
250 // IE shows a cross that img is not loaded 248 // IE shows a cross that img is not loaded
251 return INET_E_REDIRECT_FAILED; 249 return INET_E_REDIRECT_FAILED;
252 } 250 }
253 if (contentType == CFilter::contentTypeSubdocument && isBlocked) 251 if (CFilter::EContentType::contentTypeSubdocument == m_contentType)
254 { 252 {
255 PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent = true; 253 PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent = true;
256 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
257
258 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/html"); 254 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/html");
259 m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static _cast<ULONG>(g_myPageBlocked.size())); 255 m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static _cast<ULONG>(g_blockedByABPPage.size()));
260 handled = true;
261 return S_OK; 256 return S_OK;
262 } 257 }
263 if (contentType == CFilter::contentTypeScript && isBlocked) 258 if (CFilter::EContentType::contentTypeScript == m_contentType)
264 { 259 {
265 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
266 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/javascript"); 260 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/javascript");
267 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); 261 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
268 handled = true;
269 return INET_E_REDIRECT_FAILED; 262 return INET_E_REDIRECT_FAILED;
270 } 263 }
271 if (contentType == CFilter::contentTypeXmlHttpRequest && isBlocked) 264 if (CFilter::EContentType::contentTypeXmlHttpRequest == m_contentType)
272 { 265 {
273 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
274 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); 266 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
275 handled = true;
276 return INET_E_REDIRECT_FAILED; 267 return INET_E_REDIRECT_FAILED;
277 } 268 }
278 if (isBlocked) 269 if (CFilter::EContentType::contentTypeAny != m_contentType)
279 { 270 {
280 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol); 271 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
281 m_spInternetProtocolSink->ReportResult(S_FALSE, 0, L"");
282 handled = true;
283 return INET_E_REDIRECT_FAILED; 272 return INET_E_REDIRECT_FAILED;
284 } 273 }
285 } 274 }
286 #endif // SUPPORT_FILTER 275 #endif // SUPPORT_FILTER
287 276
288 return isBlocked ? S_FALSE : BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInf o, grfPI, dwReserved, pTargetProtocol); 277 return isBlocked ? S_FALSE : hr;
289 } 278 }
290 279
291
292 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) 280 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead)
293 { 281 {
294 if (nullptr == pv) 282 if (pv == nullptr)
295 { 283 {
296 return E_POINTER; 284 return E_POINTER;
297 } 285 }
298 if (nullptr == pcbRead) 286 if (pcbRead == nullptr)
299 { 287 {
300 return E_POINTER; 288 return E_POINTER;
301 } 289 }
302 *pcbRead = 0; 290 *pcbRead = 0;
303 291
304 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent) 292 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent)
305 { 293 {
306 ULONG myPageSize = static_cast<ULONG>(g_myPageBlocked.size()); 294 ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size());
307 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(g_myPageBlocked.s ize() - m_currentPositionOfSentPage)); 295 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS ize - m_currentPositionOfSentPage));
308 if (0 == positionGrow) { 296 if (positionGrow == 0) {
309 return S_FALSE; 297 return S_FALSE;
310 } 298 }
311 std::copy(g_myPageBlocked.begin(), g_myPageBlocked.begin() + positionGrow, 299 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row,
312 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); 300 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb));
313 *pcbRead = positionGrow; 301 *pcbRead = positionGrow;
314 m_currentPositionOfSentPage += positionGrow; 302 m_currentPositionOfSentPage += positionGrow;
315 303
316 if (m_spInternetProtocolSink) 304 if (m_spInternetProtocolSink)
317 { 305 {
318 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, 306 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION,
319 static_cast<ULONG>(m_currentPositionOfSentPage), myPageSize); 307 static_cast<ULONG>(m_currentPositionOfSentPage), blockedByABPPageSize);
320 } 308 }
321 if (myPageSize == m_currentPositionOfSentPage && m_spInternetProtocolSink) 309 if (blockedByABPPageSize == m_currentPositionOfSentPage && m_spInternetProto colSink)
322 { 310 {
323 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, myPageSize, myPageSize); 311 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, blockedByABP PageSize, blockedByABPPageSize);
324 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); 312 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr);
325 } 313 }
326 return S_OK; 314 return S_OK;
327 } 315 }
328 return m_pTargetProtocol->Read(pv, cb, pcbRead); 316 return m_pTargetProtocol->Read(pv, cb, pcbRead);
329 } 317 }
330 STDMETHODIMP WBPassthruSink::Switch( 318 STDMETHODIMP WBPassthruSink::Switch(
331 /* [in] */ PROTOCOLDATA *pProtocolData) 319 /* [in] */ PROTOCOLDATA *pProtocolData)
332 { 320 {
333 ATLASSERT(m_spInternetProtocolSink != 0); 321 ATLASSERT(m_spInternetProtocolSink != 0);
(...skipping 13 matching lines...) Expand all
347 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call 335 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call
348 IInternetProtocol::Continue on the main thread. 336 IInternetProtocol::Continue on the main thread.
349 337
350 Or, if you happen to have a window handy that was created on the main 338 Or, if you happen to have a window handy that was created on the main
351 thread, you can post yourself a message. 339 thread, you can post yourself a message.
352 " 340 "
353 */ 341 */
354 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED; 342 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED;
355 } 343 }
356 344
357 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) 345 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
358 { 346 {
359 if (pszAdditionalHeaders) 347 if (pszAdditionalHeaders)
360 { 348 {
361 *pszAdditionalHeaders = 0; 349 *pszAdditionalHeaders = nullptr;
362 } 350 }
363 351
352 CPluginClient* client = nullptr;
353 if (CFilter::EContentType::contentTypeAny == m_contentType && (client = CPlugi nClient::GetInstance()))
354 {
355 auto acceptHeader = [&]() -> std::string
356 {
357 // Despite there is HTTP_QUERY_ACCEPT and other query info flags, they don 't work here,
358 // only HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS does dork.
359 ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo;
360 HRESULT hr = m_spTargetProtocol->QueryInterface(&winInetHttpInfo);
361 if(FAILED(hr))
362 {
363 return "";
364 }
365 DWORD size = 0;
366 DWORD flags = 0;
367 hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_F LAG_REQUEST_HEADERS,
368 /*buffer*/nullptr, /* get size */&size, &flags, /*reserved*/ 0);
369 if(FAILED(hr))
370 {
371 return "";
372 }
373 std::string buf(size, '\0');
374 hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_F LAG_REQUEST_HEADERS,
375 &buf[0], &size, &flags, 0);
376 if(FAILED(hr))
377 {
378 return "";
379 }
380 char acceptHeader[] = "Accept:";
381 auto acceptHeaderBeginsAt = buf.find(acceptHeader);
382 if (std::string::npos == acceptHeaderBeginsAt)
383 {
384 return "";
385 }
386 acceptHeaderBeginsAt += sizeof(acceptHeader);
387 auto acceptHeaderEndsAt = buf.find("\n", acceptHeaderBeginsAt);
388 if (std::string::npos == acceptHeaderEndsAt)
389 {
390 return "";
391 }
392 return buf.substr(acceptHeaderBeginsAt, acceptHeaderEndsAt - acceptHeaderB eginsAt);
393 }();
394 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str() ));
395 bool isBlocked = client->ShouldBlock(szURL, m_contentType, m_boundDomain, /* debug flag but must be set*/true);
396 if (isBlocked)
397 {
398 m_blockedInTransaction = true;
399 return E_ABORT;
400 }
401 }
364 CComPtr<IHttpNegotiate> spHttpNegotiate; 402 CComPtr<IHttpNegotiate> spHttpNegotiate;
365 QueryServiceFromClient(&spHttpNegotiate); 403 QueryServiceFromClient(&spHttpNegotiate);
366 return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader s,dwReserved, pszAdditionalHeaders) : S_OK; 404 return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader s,dwReserved, pszAdditionalHeaders) : S_OK;
367 } 405 }
368 406
369 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) 407 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
370 { 408 {
371 if (pszAdditionalRequestHeaders) 409 if (pszAdditionalRequestHeaders)
372 { 410 {
373 *pszAdditionalRequestHeaders = 0; 411 *pszAdditionalRequestHeaders = 0;
374 } 412 }
375 413
376 CComPtr<IHttpNegotiate> spHttpNegotiate; 414 CComPtr<IHttpNegotiate> spHttpNegotiate;
377 QueryServiceFromClient(&spHttpNegotiate); 415 QueryServiceFromClient(&spHttpNegotiate);
378 416
379 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; 417 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK;
380 } 418 }
381 419
382 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus Text) 420 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus Text)
383 { 421 {
384 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS tatusCode, szStatusText) : S_OK; 422 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS tatusCode, szStatusText) : S_OK;
385 } 423 }
386 424
425 STDMETHODIMP WBPassthruSink::ReportResult(/* [in] */ HRESULT hrResult, /* [in] * / DWORD dwError, /* [in] */ LPCWSTR szResult)
426 {
427 if (m_blockedInTransaction)
428 {
429 // Don't notify the client about aborting of the operation, thus don't call BaseClass::ReportResult.
430 // Current method is called by the original protocol implementation and we a re intercepting the
431 // call here and eating it, we will call the proper ReportResult later by ou rself.
432 return S_OK;
433 }
434 return BaseClass::ReportResult(hrResult, dwError, szResult);
435 }
436
437
387 WBPassthru::WBPassthru() 438 WBPassthru::WBPassthru()
388 : m_shouldSupplyCustomContent(false) 439 : m_shouldSupplyCustomContent(false)
440 , m_hasOriginalStartCalled(false)
389 { 441 {
390 } 442 }
391 443
392 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink , 444 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink ,
393 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) 445 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved)
394 { 446 {
395 ATLASSERT(m_spInternetProtocol != 0); 447 ATLASSERT(m_spInternetProtocol != 0);
396 if (!m_spInternetProtocol) 448 if (!m_spInternetProtocol)
397 { 449 {
398 return E_UNEXPECTED; 450 return E_UNEXPECTED;
399 } 451 }
400 452
401 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol); 453 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol);
402 } 454 }
403 455
404 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead) 456 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead)
405 { 457 {
406 WBPassthruSink* pSink = GetSink(); 458 WBPassthruSink* pSink = GetSink();
407 return pSink->OnRead(pv, cb, pcbRead); 459 return pSink->OnRead(pv, cb, pcbRead);
408 } 460 }
409 461
410 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) 462 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options)
411 { 463 {
412 if (m_shouldSupplyCustomContent) 464 if (!m_hasOriginalStartCalled)
413 { 465 {
414 return S_OK; 466 return S_OK;
415 } 467 }
416 return PassthroughAPP::CInternetProtocol<WBStartPolicy>::LockRequest(options); 468 return BaseClass::LockRequest(options);
417 } 469 }
418 470
419 STDMETHODIMP WBPassthru::UnlockRequest() 471 STDMETHODIMP WBPassthru::UnlockRequest()
420 { 472 {
421 if (m_shouldSupplyCustomContent) 473 if (!m_hasOriginalStartCalled)
422 { 474 {
423 return S_OK; 475 return S_OK;
424 } 476 }
425 return PassthroughAPP::CInternetProtocol<WBStartPolicy>::UnlockRequest(); 477 return BaseClass::UnlockRequest();
426 } 478 }
OLDNEW
« no previous file with comments | « src/plugin/PluginWbPassThrough.h ('k') | src/plugin/SinkPolicy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld