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

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

Issue 29330403: Issue #1467, #3397 - Rewrite the map from threads to tabs (Closed)
Left Patch Set: Created Nov. 22, 2015, 8:17 p.m.
Right Patch Set: add comment; new function body Created July 17, 2016, 4:01 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
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
(...skipping 19 matching lines...) Expand all
33 "<!-- blocked by AdblockPlus -->" 33 "<!-- blocked by AdblockPlus -->"
34 "</body>" 34 "</body>"
35 "</html>"; 35 "</html>";
36 36
37 template <typename T> 37 template <typename T>
38 T ASCIIStringToLower(const T& text) 38 T ASCIIStringToLower(const T& text)
39 { 39 {
40 T textlower; 40 T textlower;
41 std::transform(text.begin(), text.end(), std::back_inserter(textlower), 41 std::transform(text.begin(), text.end(), std::back_inserter(textlower),
42 [](T::value_type ch) 42 [](T::value_type ch)
43 » { 43 {
44 » return std::tolower(ch, std::locale()); 44 return std::tolower(ch, std::locale());
45 » } 45 }
46 » ); 46 );
47 return textlower; 47 return textlower;
48 } 48 }
49 49
50 typedef AdblockPlus::FilterEngine::ContentType ContentType; 50 typedef AdblockPlus::FilterEngine::ContentType ContentType;
51 51
52 template <class T> 52 template <class T>
53 T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c onst T& delimiter) 53 T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c onst T& delimiter)
54 { 54 {
55 const T allHeadersLower = ASCIIStringToLower(allHeaders); 55 const T allHeadersLower = ASCIIStringToLower(allHeaders);
56 auto targetHeaderBeginsAt = allHeadersLower.find(ASCIIStringToLower(targetHe aderNameWithColon)); 56 auto targetHeaderBeginsAt = allHeadersLower.find(ASCIIStringToLower(targetHe aderNameWithColon));
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 135 }
136 } 136 }
137 137
138 WBPassthruSink::WBPassthruSink() 138 WBPassthruSink::WBPassthruSink()
139 : m_currentPositionOfSentPage(0) 139 : m_currentPositionOfSentPage(0)
140 , m_contentType(ContentType::CONTENT_TYPE_OTHER) 140 , m_contentType(ContentType::CONTENT_TYPE_OTHER)
141 , m_isCustomResponse(false) 141 , m_isCustomResponse(false)
142 { 142 {
143 } 143 }
144 144
145 ContentType WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) 145 namespace
146 { 146 {
147 if (mimeType.Find(L"image/") >= 0) 147 /**
148 { 148 * Heuristic to infer an ABP content type from the media type list of an Accep t: header field.
149 return ContentType::CONTENT_TYPE_IMAGE; 149 *
150 } 150 * Known IE Accept: strings for documents and images:
151 if (mimeType.Find(L"text/css") >= 0) 151 * text/html, application/xhtml+xml, image/jxr, *\/*
152 { 152 * image/png, image/svg+xml, image/jxr, image/*;q=0.8, *\/*;q = 0.5
153 return ContentType::CONTENT_TYPE_STYLESHEET; 153 * In IE9 the image/jxr part is missing.
154 } 154 */
155 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0)) 155 ContentType InferContentTypeFromMediaTypeList(const std::wstring& mediaTypeLis t)
156 { 156 {
157 return ContentType::CONTENT_TYPE_SCRIPT; 157 if ((mediaTypeList.find(L"text/html") != std::wstring::npos) ||
158 } 158 (mediaTypeList.find(L"application/xhtml+xml") != std::wstring::npos))
159 if (mimeType.Find(L"application/x-shockwave-flash") >= 0) 159 {
160 { 160 return ContentType::CONTENT_TYPE_SUBDOCUMENT;
161 return ContentType::CONTENT_TYPE_OBJECT; 161 }
162 } 162 if (mediaTypeList.find(L"image/") != std::wstring::npos)
163 if (mimeType.Find(L"text/html") >= 0) 163 {
164 { 164 return ContentType::CONTENT_TYPE_IMAGE;
165 return ContentType::CONTENT_TYPE_SUBDOCUMENT; 165 }
166 } 166 if (mediaTypeList.find(L"text/css") != std::wstring::npos)
167 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example 167 {
168 if (mimeType.Find(L"xml") >= 0) 168 return ContentType::CONTENT_TYPE_STYLESHEET;
169 { 169 }
170 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; 170 if ((mediaTypeList.find(L"application/javascript") != std::wstring::npos) || (mediaTypeList.find(L"application/json") != std::wstring::npos))
171 } 171 {
172 172 return ContentType::CONTENT_TYPE_SCRIPT;
173 return ContentType::CONTENT_TYPE_OTHER; 173 }
174 } 174 if (mediaTypeList.find(L"application/x-shockwave-flash") != std::wstring::np os)
175 175 {
176 ContentType WBPassthruSink::GetContentTypeFromURL(const std::wstring& src) 176 return ContentType::CONTENT_TYPE_OBJECT;
177 { 177 }
178 std::wstring schemeAndHierarchicalPart = GetSchemeAndHierarchicalPart(src); 178 // It is important to have this check last, since it is rather generic, and might overlay text/html, for example
179 auto contentType = GetContentTypeFromString(schemeAndHierarchicalPart); 179 if (mediaTypeList.find(L"xml") != std::wstring::npos)
180 if (contentType == ContentType::CONTENT_TYPE_OTHER && 180 {
181 AdblockPlus::IE::InstalledMajorVersion() == 8) 181 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
182 { 182 }
183 std::wstring queryString = GetQueryString(src); 183 return ContentType::CONTENT_TYPE_OTHER;
184 wchar_t* nextToken = nullptr; 184 }
185 const wchar_t* token = wcstok_s(&queryString[0], L"&=", &nextToken); 185
186 while (token != nullptr) 186 ContentType InferContentTypeFromUrl(const std::wstring& src)
187 { 187 {
188 contentType = GetContentTypeFromString(token); 188 std::wstring schemeAndHierarchicalPart = GetSchemeAndHierarchicalPart(src);
189 if (contentType != ContentType::CONTENT_TYPE_OTHER) 189 auto contentType = GetContentTypeFromString(schemeAndHierarchicalPart);
190 if (contentType == ContentType::CONTENT_TYPE_OTHER &&
191 AdblockPlus::IE::InstalledMajorVersion() == 8)
192 {
193 std::wstring queryString = GetQueryString(src);
194 wchar_t* nextToken = nullptr;
195 const wchar_t* token = wcstok_s(&queryString[0], L"&=", &nextToken);
196 while (token != nullptr)
190 { 197 {
191 return contentType; 198 contentType = GetContentTypeFromString(token);
199 if (contentType != ContentType::CONTENT_TYPE_OTHER)
200 {
201 return contentType;
202 }
203 token = wcstok_s(nullptr, L"&=", &nextToken);
192 } 204 }
193 token = wcstok_s(nullptr, L"&=", &nextToken); 205 }
194 } 206 return contentType;
195 } 207 }
196 return contentType; 208
197 } 209 ContentType InferContentType(const std::wstring& mediaTypeList, const std::wst ring& domain, const std::wstring& src)
198 210 {
199 ContentType WBPassthruSink::GetContentType(const CString& mimeType, const std::w string& domain, const std::wstring& src) 211 // No referer or mime type
200 { 212 // BINDSTRING_XDR_ORIGIN works only for IE v8+
201 // No referer or mime type 213 if (mediaTypeList.empty() && domain.empty() && AdblockPlus::IE::InstalledMaj orVersion() >= 8)
202 // BINDSTRING_XDR_ORIGIN works only for IE v8+ 214 {
203 if (mimeType.IsEmpty() && domain.empty() && AdblockPlus::IE::InstalledMajorVer sion() >= 8) 215 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
204 { 216 }
205 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; 217 ContentType contentType = InferContentTypeFromMediaTypeList(mediaTypeList);
206 } 218 if (contentType == ContentType::CONTENT_TYPE_OTHER)
207 ContentType contentType = GetContentTypeFromMimeType(mimeType); 219 {
208 if (contentType == ContentType::CONTENT_TYPE_OTHER) 220 contentType = InferContentTypeFromUrl(src);
209 { 221 }
210 contentType = GetContentTypeFromURL(src); 222 return contentType;
211 } 223 }
212 return contentType;
213 } 224 }
214 225
215 //////////////////////////////////////////////////////////////////////////////// //////// 226 //////////////////////////////////////////////////////////////////////////////// ////////
216 //WBPassthruSink 227 //WBPassthruSink
217 //Monitor and/or cancel every request and responde 228 //Monitor and/or cancel every request and responde
218 //WB makes, including images, sounds, scripts, etc 229 //WB makes, including images, sounds, scripts, etc
219 //////////////////////////////////////////////////////////////////////////////// //////// 230 //////////////////////////////////////////////////////////////////////////////// ////////
220 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, 231 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k,
221 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, 232 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved,
222 IInternetProtocol* pTargetProtocol, bool& handle d) 233 IInternetProtocol* pTargetProtocol)
223 { 234 {
224 m_pTargetProtocol = pTargetProtocol; 235 m_pTargetProtocol = pTargetProtocol;
225 return BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); 236 return BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol);
226 } 237 }
227 238
228 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) 239 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead)
229 { 240 {
230 if (!pv || !pcbRead) 241 if (!pv || !pcbRead)
231 { 242 {
232 return E_POINTER; 243 return E_POINTER;
233 } 244 }
234 *pcbRead = 0; 245 *pcbRead = 0;
235 246
236 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent) 247 if (PassthroughAPP::CustomSinkStartPolicy<WbPassthroughProtocol, WBPassthruSin k>::GetProtocol(this)->m_shouldSupplyCustomContent)
237 { 248 {
238 ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size()); 249 ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size());
239 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS ize - m_currentPositionOfSentPage)); 250 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS ize - m_currentPositionOfSentPage));
240 if (positionGrow == 0) { 251 if (positionGrow == 0) {
241 return S_FALSE; 252 return S_FALSE;
242 } 253 }
243 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row, 254 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row,
244 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); 255 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb));
245 *pcbRead = positionGrow; 256 *pcbRead = positionGrow;
246 m_currentPositionOfSentPage += positionGrow; 257 m_currentPositionOfSentPage += positionGrow;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 return false; 329 return false;
319 } 330 }
320 331
321 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) 332 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
322 { 333 {
323 if (!szURL) 334 if (!szURL)
324 { 335 {
325 return E_POINTER; 336 return E_POINTER;
326 } 337 }
327 std::wstring src = szURL; 338 std::wstring src = szURL;
328 UnescapeUrl(src);
329 DEBUG_GENERAL(src); 339 DEBUG_GENERAL(src);
330
331 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol);
332 340
333 if (pszAdditionalHeaders) 341 if (pszAdditionalHeaders)
334 { 342 {
335 *pszAdditionalHeaders = nullptr; 343 *pszAdditionalHeaders = nullptr;
336 } 344 }
337 345
338 CComPtr<IHttpNegotiate> httpNegotiate; 346 CComPtr<IHttpNegotiate> httpNegotiate;
339 QueryServiceFromClient(&httpNegotiate); 347 QueryServiceFromClient(&httpNegotiate);
340 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need. 348 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need.
341 // There doesn't seem to be any other way to get this header before the reques t has been made. 349 // There doesn't seem to be any other way to get this header before the reques t has been made.
342 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; 350 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK;
343 351
344 if (pszAdditionalHeaders && *pszAdditionalHeaders) 352 if (pszAdditionalHeaders && *pszAdditionalHeaders)
345 { 353 {
346 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n"); 354 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n");
347 } 355 }
348 m_boundDomain = TrimString(m_boundDomain); 356 m_boundDomain = TrimString(m_boundDomain);
349 m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDoma in, src); 357 m_contentType = InferContentType(ToUtf16String(ExtractHttpAcceptHeader(m_spTar getProtocol)), m_boundDomain, src);
350 358
351 CPluginTab* tab = CPluginClass::GetTabCurrentThread(); 359 CPluginTab* tab = CPluginClass::GetTabForCurrentThread();
352 CPluginClient* client = CPluginClient::GetInstance(); 360 CPluginClient* client = CPluginClient::GetInstance();
353 361
354 if (tab && client) 362 if (tab && client)
355 { 363 {
356 std::wstring documentUrl = tab->GetDocumentUrl(); 364 std::wstring documentUrl = tab->GetDocumentUrl();
357 // Page is identical to document => don't block 365 // Page is identical to document => don't block
358 if (documentUrl == src) 366 if (documentUrl == src)
359 { 367 {
360 return nativeHr; 368 return nativeHr;
361 } 369 }
362 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(documentUrl)) 370 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(documentUrl))
363 { 371 {
364 if (tab->IsFrameCached(src)) 372 if (tab->IsFrameCached(src))
365 { 373 {
366 m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT; 374 m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT;
367 } 375 }
368 } 376 }
369 } 377 }
370 378
371 if (IsFlashRequest(pszAdditionalHeaders)) 379 if (IsFlashRequest(pszAdditionalHeaders))
372 { 380 {
373 m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST; 381 m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST;
374 } 382 }
375 383
376 if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi tionalHeaders)) 384 if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi tionalHeaders))
377 { 385 {
378 m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST; 386 m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
379 } 387 }
380 388
381 if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but must be set*/true)) 389 if (client->ShouldBlock(src, m_contentType, m_boundDomain, /*debug flag but mu st be set*/true))
382 { 390 {
383 // NOTE: Feeding custom HTML to Flash, instead of original object subrequest 391 // NOTE: Feeding custom HTML to Flash, instead of original object subrequest
384 // doesn't have much sense. It also can manifest in unwanted result 392 // doesn't have much sense. It also can manifest in unwanted result
385 // like video being blocked (See https://issues.adblockplus.org/ticket/1669) 393 // like video being blocked (See https://issues.adblockplus.org/ticket/1669)
386 // So we report blocked object subrequests as failed, not just empty HTML. 394 // So we report blocked object subrequests as failed, not just empty HTML.
387 m_isCustomResponse = m_contentType != ContentType::CONTENT_TYPE_OBJECT_SUBRE QUEST; 395 m_isCustomResponse = m_contentType != ContentType::CONTENT_TYPE_OBJECT_SUBRE QUEST;
388 return E_ABORT; 396 return E_ABORT;
389 } 397 }
390 return nativeHr; 398 return nativeHr;
391 } 399 }
(...skipping 21 matching lines...) Expand all
413 if (m_isCustomResponse) 421 if (m_isCustomResponse)
414 { 422 {
415 // Don't notify the client about aborting of the operation, thus don't call BaseClass::ReportResult. 423 // Don't notify the client about aborting of the operation, thus don't call BaseClass::ReportResult.
416 // Current method is called by the original protocol implementation and we a re intercepting the 424 // Current method is called by the original protocol implementation and we a re intercepting the
417 // call here and eating it, we will call the proper ReportResult later by ou rself. 425 // call here and eating it, we will call the proper ReportResult later by ou rself.
418 return S_OK; 426 return S_OK;
419 } 427 }
420 return BaseClass::ReportResult(hrResult, dwError, szResult); 428 return BaseClass::ReportResult(hrResult, dwError, szResult);
421 } 429 }
422 430
423 431 HRESULT WbPassthroughSinkStartPolicy::OnStart(LPCWSTR szUrl,
424 WBPassthru::WBPassthru() 432 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
425 : m_shouldSupplyCustomContent(false) 433 DWORD grfPI, HANDLE_PTR dwReserved,
426 { 434 IInternetProtocol* pTargetProtocol)
427 } 435 {
428 436 HRESULT hr = BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwRese rved, pTargetProtocol);
429 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink , 437 WBPassthruSink* pSink = GetSink();
438 if (hr == E_ABORT && pSink->m_isCustomResponse)
439 {
440 GetProtocol(pSink)->m_shouldSupplyCustomContent = true;
441 pSink->m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE , L"text/html");
442 pSink->m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, s tatic_cast<ULONG>(g_blockedByABPPage.size()));
443 return S_OK;
444 }
445 return hr;
446 }
447
448 STDMETHODIMP WbPassthroughProtocol::Start(LPCWSTR szUrl, IInternetProtocolSink * pOIProtSink,
430 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) 449 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved)
431 { 450 {
432 ATLASSERT(m_spInternetProtocol != 0); 451 ATLASSERT(m_spInternetProtocol != 0);
433 if (!m_spInternetProtocol) 452 if (!m_spInternetProtocol)
434 { 453 {
435 return E_UNEXPECTED; 454 return E_UNEXPECTED;
436 } 455 }
437 456
438 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol); 457 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol);
439 } 458 }
440 459
441 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead) 460 STDMETHODIMP WbPassthroughProtocol::Read(/* [in, out] */ void *pv,/* [in] */ ULO NG cb,/* [out] */ ULONG *pcbRead)
442 { 461 {
443 WBPassthruSink* pSink = GetSink(); 462 WBPassthruSink* pSink = GetSink();
444 return pSink->OnRead(pv, cb, pcbRead); 463 return pSink->OnRead(pv, cb, pcbRead);
445 } 464 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld