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

Delta Between Two Patch Sets: src/plugin/PluginWbPassThrough.cpp

Issue 6299667012780032: Issues #696,1231,1264,1265 - Improve handling in PassthroughApp (Closed)
Left Patch Set: Created Sept. 19, 2014, 2:41 p.m.
Right Patch Set: rebase Created Oct. 17, 2014, 12:51 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/plugin/PluginWbPassThrough.h ('k') | src/plugin/SinkPolicy.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
7 #include "PluginFilter.h" 6 #include "PluginFilter.h"
8 #endif
9 #include "PluginSettings.h" 7 #include "PluginSettings.h"
10 #include "PluginClass.h" 8 #include "PluginClass.h"
11 #include "PluginSystem.h" 9 #include "PluginSystem.h"
12 #include <WinInet.h> 10 #include <WinInet.h>
13 #include "wtypes.h" 11 #include "wtypes.h"
14 12
15 namespace 13 namespace
16 { 14 {
17 std::string g_blockedByABPPage = "<!DOCTYPE html>" 15 std::string g_blockedByABPPage = "<!DOCTYPE html>"
18 "<html>" 16 "<html>"
19 "<body>" 17 "<body>"
20 "<!-- blocked by AdblockPlus -->" 18 "<!-- blocked by AdblockPlus -->"
21 "</body>" 19 "</body>"
22 "</html>"; 20 "</html>";
23 } 21 }
24 22
25 WBPassthruSink::WBPassthruSink() 23 WBPassthruSink::WBPassthruSink()
26 : m_currentPositionOfSentPage(0) 24 : m_currentPositionOfSentPage(0)
Oleksandr 2014/09/21 23:30:40 I wouldn't be entirely sure that IE does not reuse
sergei 2014/09/22 16:18:05 It does not reuse them. If it happens we will be a
Oleksandr 2014/10/03 14:36:37 Even though I can't provide an example when this m
27 , m_contentType(CFilter::EContentType::contentTypeAny) 25 , m_contentType(CFilter::EContentType::contentTypeAny)
28 , m_blockedInTransaction(false) 26 , m_blockedInTransaction(false)
29 { 27 {
30 } 28 }
31 29
32 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) 30 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType)
33 { 31 {
34 if (mimeType.Find(L"image/") >= 0) 32 if (mimeType.Find(L"image/") >= 0)
35 { 33 {
36 return CFilter::contentTypeImage; 34 return CFilter::contentTypeImage;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 { 92 {
95 return CFilter::contentTypeObject; 93 return CFilter::contentTypeObject;
96 } 94 }
97 else if (ext == L".jsp" || ext == L".php" || ext == L".html") 95 else if (ext == L".jsp" || ext == L".php" || ext == L".html")
98 { 96 {
99 return CFilter::contentTypeSubdocument; 97 return CFilter::contentTypeSubdocument;
100 } 98 }
101 return CFilter::contentTypeAny; 99 return CFilter::contentTypeAny;
102 } 100 }
103 101
104 int WBPassthruSink::GetContentType(const CString& mimeType, const CString& domai n, const CString& src) 102 int WBPassthruSink::GetContentType(const CString& mimeType, const std::wstring& domain, const CString& src)
105 { 103 {
106 // No referer or mime type 104 // No referer or mime type
107 // BINDSTRING_XDR_ORIGIN works only for IE v8+ 105 // BINDSTRING_XDR_ORIGIN works only for IE v8+
108 if (mimeType.IsEmpty() && domain.IsEmpty() && CPluginClient::GetInstance()->Ge tIEVersion() >= 8) 106 if (mimeType.IsEmpty() && domain.empty() && CPluginClient::GetInstance()->GetI EVersion() >= 8)
109 { 107 {
110 return CFilter::contentTypeXmlHttpRequest; 108 return CFilter::contentTypeXmlHttpRequest;
111 } 109 }
112 int contentType = GetContentTypeFromMimeType(mimeType); 110 int contentType = GetContentTypeFromMimeType(mimeType);
113 if (contentType == CFilter::contentTypeAny) 111 if (contentType == CFilter::contentTypeAny)
114 { 112 {
115 contentType = GetContentTypeFromURL(src); 113 contentType = GetContentTypeFromURL(src);
116 } 114 }
117 return contentType; 115 return contentType;
118 } 116 }
119 117
120 //////////////////////////////////////////////////////////////////////////////// //////// 118 //////////////////////////////////////////////////////////////////////////////// ////////
121 //WBPassthruSink 119 //WBPassthruSink
122 //Monitor and/or cancel every request and responde 120 //Monitor and/or cancel every request and responde
123 //WB makes, including images, sounds, scripts, etc 121 //WB makes, including images, sounds, scripts, etc
124 //////////////////////////////////////////////////////////////////////////////// //////// 122 //////////////////////////////////////////////////////////////////////////////// ////////
125 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, 123 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k,
126 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, 124 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved,
127 IInternetProtocol* pTargetProtocol, bool& handle d) 125 IInternetProtocol* pTargetProtocol, bool& handle d)
128 { 126 {
129 m_pTargetProtocol = pTargetProtocol; 127 m_pTargetProtocol = pTargetProtocol;
130 bool isBlocked = false; 128 bool isBlocked = false;
131 CString src = szUrl; 129 CString src = szUrl;
132 DEBUG_GENERAL(src); 130 DEBUG_GENERAL(src);
133 CPluginClient::UnescapeUrl(src); 131 CPluginClient::UnescapeUrl(src);
134 132
135 // call the impl of the base class as soon as possible because it initializes the base class 133 // 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. 134 // members, used by this method. It queries for the required interfaces.
137 HRESULT hr = BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwRese rved, pTargetProtocol); 135 HRESULT hr = BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwRese rved, pTargetProtocol);
Oleksandr 2014/09/21 23:30:40 I still have my concerns if the requests are actua
sergei 2014/09/22 16:18:05 I have checked it before and now again, it works i
Oleksandr 2014/10/03 14:36:37 Not really. Just wanted to double check if you've
138 if (FAILED(hr)) 136 if (FAILED(hr))
139 { 137 {
140 return hr; 138 return hr;
141 } 139 }
142 140
143 CString mimeType; 141 CString mimeType;
144 if (pOIBindInfo) 142 if (pOIBindInfo)
145 { 143 {
146 ULONG resLen = 0; 144 ULONG resLen = 0;
147 145
(...skipping 17 matching lines...) Expand all
165 } 163 }
166 } 164 }
167 // We can obtain IBindCtx* here, but IEnumString obtained via IBindCtx::Enum ObjectParam 165 // We can obtain IBindCtx* here, but IEnumString obtained via IBindCtx::Enum ObjectParam
168 // does not return any parameter, so it's useless. 166 // does not return any parameter, so it's useless.
169 } 167 }
170 168
171 CString cookie; 169 CString cookie;
172 ULONG len1 = 2048; 170 ULONG len1 = 2048;
173 ULONG len2 = 2048; 171 ULONG len2 = 2048;
174 172
175 #ifdef SUPPORT_FILTER
176 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); 173 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
177 CPluginClient* client = CPluginClient::GetInstance(); 174 CPluginClient* client = CPluginClient::GetInstance();
178 175
179 if (tab && client) 176 if (tab && client)
180 { 177 {
181 CString documentUrl = tab->GetDocumentUrl(); 178 CString documentUrl = tab->GetDocumentUrl();
182 // Page is identical to document => don't block 179 // Page is identical to document => don't block
183 if (documentUrl == src) 180 if (documentUrl == src)
184 { 181 {
185 // fall through 182 // fall through
186 } 183 }
187 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl))) 184 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl)))
188 { 185 {
189 m_boundDomain = tab->GetDocumentUrl(); 186 m_boundDomain = tab->GetDocumentUrl();
190 m_contentType = CFilter::contentTypeAny; 187 m_contentType = CFilter::contentTypeAny;
191 #ifdef SUPPORT_FRAME_CACHING 188 if (tab != nullptr && tab->IsFrameCached(src))
192 if (nullptr != tab && tab->IsFrameCached(src))
Oleksandr 2014/09/21 23:30:40 No yoda conditions, please if (tab != nullptr && .
193 { 189 {
194 m_contentType = CFilter::contentTypeSubdocument; 190 m_contentType = CFilter::contentTypeSubdocument;
195 } 191 }
196 else 192 else
197 #endif // SUPPORT_FRAME_CACHING
198 { 193 {
199 m_contentType = GetContentType(mimeType, m_boundDomain, src); 194 m_contentType = GetContentType(mimeType, m_boundDomain, src);
200 } 195 }
201 } 196 }
202 } 197 }
203 198
204 if (nullptr == tab) 199 if (tab == nullptr)
Oleksandr 2014/09/21 23:30:40 No yoda conditions, please
205 { 200 {
206 m_contentType = GetContentType(mimeType, m_boundDomain, src); 201 m_contentType = GetContentType(mimeType, m_boundDomain, src);
207 } 202 }
208 203
209 { 204 {
210 // Here is the heuristic which detects the requests issued by Flash.ocx. 205 // Here is the heuristic which detects the requests issued by Flash.ocx.
211 // It turned out that the implementation from ''Flash.ocx'' (tested version is 15.0.0.152) 206 // 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' 207 // 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 208 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often i ncludes something
214 // else. 209 // else.
215 ATL::CComPtr<IBindStatusCallback> bscb; 210 ATL::CComPtr<IBindStatusCallback> bscb;
216 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb) 211 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb)
217 { 212 {
218 DWORD grfBINDF = 0; 213 DWORD grfBINDF = 0;
219 BINDINFO bindInfo = {}; 214 BINDINFO bindInfo = {};
220 bindInfo.cbSize = sizeof(bindInfo); 215 bindInfo.cbSize = sizeof(bindInfo);
221 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) 216 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo))
222 && (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF 217 && (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF
223 && (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindInfo.dwOptions 218 && (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindInfo.dwOptions
224 ) 219 )
Oleksandr 2014/09/21 23:30:40 This looks quite neat, however can you maybe test
sergei 2014/09/22 16:18:05 I will test it with different <IE, Flash> as far a
225 { 220 {
226 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; 221 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest;
227 } 222 }
228 } 223 }
229 } 224 }
230 225
231 // The descision about EContentType::contentTypeAny is made later in 226 // The descision about EContentType::contentTypeAny is made later in
232 // WBPassthruSink::BeginningTransaction. Sometimes here we cannot detect the r equest type, but 227 // 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 228 // in WBPassthruSink::BeginningTransaction the header Accept is available whic h allows to
234 // obtain the "request type" in our terminology. 229 // obtain the "request type" in our terminology.
235 if (nullptr != client 230 if (nullptr != client
236 && CFilter::EContentType::contentTypeAny != m_contentType 231 && CFilter::EContentType::contentTypeAny != m_contentType
237 && client->ShouldBlock(src, m_contentType, m_boundDomain, true)) 232 && client->ShouldBlock(static_cast<const wchar_t*>(src), m_contentType, m_bo undDomain, true))
238 { 233 {
239 isBlocked = true; 234 isBlocked = true;
240 } 235 }
241 236
242 // For IE6 and earlier there is iframe back button issue, so avoid it. 237 // For IE6 and earlier there is iframe back button issue, so avoid it.
243 if (isBlocked && client->GetIEVersion() > 6) 238 if (isBlocked && client->GetIEVersion() > 6)
244 { 239 {
245 handled = true; 240 handled = true;
246 if (CFilter::EContentType::contentTypeImage == m_contentType) 241 if (CFilter::EContentType::contentTypeImage == m_contentType)
247 { 242 {
248 // IE shows a cross that img is not loaded 243 // IE shows a cross that img is not loaded
Oleksandr 2014/09/21 23:30:40 Does this happen even if we "eat" the ReportResult
sergei 2014/09/22 16:18:05 Have not tested yet, also I'm afraid that sending
Oleksandr 2014/10/03 14:36:37 This can go into other review anyway. On 2014/09/2
249 return INET_E_REDIRECT_FAILED; 244 return INET_E_REDIRECT_FAILED;
250 } 245 }
251 if (CFilter::EContentType::contentTypeSubdocument == m_contentType) 246 if (CFilter::EContentType::contentTypeSubdocument == m_contentType)
252 { 247 {
253 PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent = true; 248 PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent = true;
254 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/html"); 249 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/html");
255 m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static _cast<ULONG>(g_blockedByABPPage.size())); 250 m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static _cast<ULONG>(g_blockedByABPPage.size()));
256 return S_OK; 251 return S_OK;
257 } 252 }
258 if (CFilter::EContentType::contentTypeScript == m_contentType) 253 if (CFilter::EContentType::contentTypeScript == m_contentType)
259 { 254 {
260 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/javascript"); 255 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/javascript");
261 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); 256 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
262 return INET_E_REDIRECT_FAILED; 257 return INET_E_REDIRECT_FAILED;
263 } 258 }
264 if (CFilter::EContentType::contentTypeXmlHttpRequest == m_contentType) 259 if (CFilter::EContentType::contentTypeXmlHttpRequest == m_contentType)
265 { 260 {
266 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); 261 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
267 return INET_E_REDIRECT_FAILED; 262 return INET_E_REDIRECT_FAILED;
268 } 263 }
269 if (CFilter::EContentType::contentTypeAny != m_contentType) 264 if (CFilter::EContentType::contentTypeAny != m_contentType)
270 { 265 {
271 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); 266 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
272 return INET_E_REDIRECT_FAILED; 267 return INET_E_REDIRECT_FAILED;
273 } 268 }
274 } 269 }
275 #endif // SUPPORT_FILTER
276 270
277 return isBlocked ? S_FALSE : hr; 271 return isBlocked ? S_FALSE : hr;
278 } 272 }
279 273
280 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) 274 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead)
281 { 275 {
282 if (nullptr == pv) 276 if (pv == nullptr)
Oleksandr 2014/09/21 23:30:40 if (pv == nullptr) looks better, imho
283 { 277 {
284 return E_POINTER; 278 return E_POINTER;
285 } 279 }
286 if (nullptr == pcbRead) 280 if (pcbRead == nullptr)
Oleksandr 2014/09/21 23:30:40 Same as above
287 { 281 {
288 return E_POINTER; 282 return E_POINTER;
289 } 283 }
290 *pcbRead = 0; 284 *pcbRead = 0;
291 285
292 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent) 286 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent)
293 { 287 {
294 ULONG myPageSize = static_cast<ULONG>(g_blockedByABPPage.size()); 288 ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size());
Oleksandr 2014/09/21 23:30:40 abpPageSize would be a better name, IMHO
sergei 2014/09/22 16:18:05 Sorry, forgot to change the name. During the playi
295 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(g_blockedByABPPag e.size() - m_currentPositionOfSentPage)); 289 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS ize - m_currentPositionOfSentPage));
296 if (0 == positionGrow) { 290 if (positionGrow == 0) {
Oleksandr 2014/09/21 23:30:40 positionGrow == 0 seems more logical
297 return S_FALSE; 291 return S_FALSE;
298 } 292 }
299 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row, 293 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row,
300 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); 294 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb));
Oleksandr 2014/09/21 23:30:40 So this will throw a runtime error if cb < positio
sergei 2014/09/22 16:18:05 - It's not possible to compile without checked ite
Oleksandr 2014/10/03 14:36:37 I suppose you could use memcpy here instead, but I
301 *pcbRead = positionGrow; 295 *pcbRead = positionGrow;
302 m_currentPositionOfSentPage += positionGrow; 296 m_currentPositionOfSentPage += positionGrow;
303 297
304 if (m_spInternetProtocolSink) 298 if (m_spInternetProtocolSink)
305 { 299 {
306 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, 300 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION,
307 static_cast<ULONG>(m_currentPositionOfSentPage), myPageSize); 301 static_cast<ULONG>(m_currentPositionOfSentPage), blockedByABPPageSize);
308 } 302 }
309 if (myPageSize == m_currentPositionOfSentPage && m_spInternetProtocolSink) 303 if (blockedByABPPageSize == m_currentPositionOfSentPage && m_spInternetProto colSink)
310 { 304 {
311 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, myPageSize, myPageSize); 305 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, blockedByABP PageSize, blockedByABPPageSize);
312 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); 306 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr);
313 } 307 }
314 return S_OK; 308 return S_OK;
315 } 309 }
316 return m_pTargetProtocol->Read(pv, cb, pcbRead); 310 return m_pTargetProtocol->Read(pv, cb, pcbRead);
317 } 311 }
318 STDMETHODIMP WBPassthruSink::Switch( 312 STDMETHODIMP WBPassthruSink::Switch(
319 /* [in] */ PROTOCOLDATA *pProtocolData) 313 /* [in] */ PROTOCOLDATA *pProtocolData)
320 { 314 {
321 ATLASSERT(m_spInternetProtocolSink != 0); 315 ATLASSERT(m_spInternetProtocolSink != 0);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 463 }
470 464
471 STDMETHODIMP WBPassthru::UnlockRequest() 465 STDMETHODIMP WBPassthru::UnlockRequest()
472 { 466 {
473 if (!m_hasOriginalStartCalled) 467 if (!m_hasOriginalStartCalled)
474 { 468 {
475 return S_OK; 469 return S_OK;
476 } 470 }
477 return BaseClass::UnlockRequest(); 471 return BaseClass::UnlockRequest();
478 } 472 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld