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

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

Issue 5316782940225536: Issue 1557 - Update to the recent libadblockplus to reduce additional updates in the logic later. (Closed)
Left Patch Set: remove debugging code Created Nov. 24, 2014, 11:09 a.m.
Right Patch Set: rebase and remove member of CFilter Created Feb. 4, 2015, 12:50 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') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
1 #include "PluginStdAfx.h" 18 #include "PluginStdAfx.h"
2 19
3 #include "PluginWbPassThrough.h" 20 #include "PluginWbPassThrough.h"
4 #include "PluginClient.h" 21 #include "PluginClient.h"
5 #include "PluginClientFactory.h" 22 #include "PluginClientFactory.h"
6 #include "PluginFilter.h" 23 #include "PluginFilter.h"
7 #include "PluginSettings.h" 24 #include "PluginSettings.h"
8 #include "PluginClass.h" 25 #include "PluginClass.h"
9 #include "PluginSystem.h" 26 #include "PluginSystem.h"
10 #include <WinInet.h> 27 #include <WinInet.h>
11 #include "wtypes.h" 28 #include "wtypes.h"
12 #include "../shared/Utils.h" 29 #include "../shared/Utils.h"
30 #include "../shared/IE_version.h"
13 31
14 namespace 32 namespace
15 { 33 {
16 const std::string g_blockedByABPPage = "<!DOCTYPE html>" 34 const std::string g_blockedByABPPage = "<!DOCTYPE html>"
17 "<html>" 35 "<html>"
18 "<body>" 36 "<body>"
19 "<!-- blocked by AdblockPlus -->" 37 "<!-- blocked by AdblockPlus -->"
20 "</body>" 38 "</body>"
21 "</html>"; 39 "</html>";
22 40
41 template <typename T>
42 T ASCIIStringToLower(const T& text)
43 {
44 T textlower;
45 std::transform(text.begin(), text.end(), std::back_inserter(textlower),
46 [](T::value_type ch)
47 {
48 return std::tolower(ch, std::locale());
49 }
50 );
51 return textlower;
52 }
53
23 typedef AdblockPlus::FilterEngine::ContentType ContentType; 54 typedef AdblockPlus::FilterEngine::ContentType ContentType;
24 55
25 template <class T> 56 template <class T>
26 T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c onst T& delimiter) 57 T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c onst T& delimiter)
27 { 58 {
28 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon); 59 const T allHeadersLower = ASCIIStringToLower(allHeaders);
60 auto targetHeaderBeginsAt = allHeadersLower.find(ASCIIStringToLower(targetHe aderNameWithColon));
29 if (targetHeaderBeginsAt == T::npos) 61 if (targetHeaderBeginsAt == T::npos)
30 { 62 {
31 return T(); 63 return T();
32 } 64 }
33 targetHeaderBeginsAt += targetHeaderNameWithColon.length(); 65 targetHeaderBeginsAt += targetHeaderNameWithColon.length();
34 auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt); 66 auto targetHeaderEndsAt = allHeadersLower.find(ASCIIStringToLower(delimiter) , targetHeaderBeginsAt);
35 if (targetHeaderEndsAt == T::npos) 67 if (targetHeaderEndsAt == T::npos)
36 { 68 {
37 return T(); 69 return T();
38 } 70 }
39 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHe aderBeginsAt); 71 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHe aderBeginsAt);
40 } 72 }
41 73
42 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol) 74 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol)
43 { 75 {
44 // Despite there being HTTP_QUERY_ACCEPT and other query info flags, they do n't work here, 76 // Despite there being HTTP_QUERY_ACCEPT and other query info flags, they do n't work here,
(...skipping 23 matching lines...) Expand all
68 100
69 bool IsXmlHttpRequest(const std::wstring& additionalHeaders) 101 bool IsXmlHttpRequest(const std::wstring& additionalHeaders)
70 { 102 {
71 auto requestedWithHeader = ExtractHttpHeader<std::wstring>(additionalHeaders , L"X-Requested-With:", L"\n"); 103 auto requestedWithHeader = ExtractHttpHeader<std::wstring>(additionalHeaders , L"X-Requested-With:", L"\n");
72 return TrimString(requestedWithHeader) == L"XMLHttpRequest"; 104 return TrimString(requestedWithHeader) == L"XMLHttpRequest";
73 } 105 }
74 } 106 }
75 107
76 WBPassthruSink::WBPassthruSink() 108 WBPassthruSink::WBPassthruSink()
77 : m_currentPositionOfSentPage(0) 109 : m_currentPositionOfSentPage(0)
78 , m_contentType(AdblockPlus::FilterEngine::ContentType::CONTENT_TYPE_OTHER) 110 , m_contentType(ContentType::CONTENT_TYPE_OTHER)
Oleksandr 2015/01/11 09:22:46 Don't we have a typedef to shorten this? Though pe
79 , m_blockedInTransaction(false) 111 , m_isCustomResponse(false)
80 { 112 {
81 } 113 }
82 114
83 ContentType WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) 115 ContentType WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType)
84 { 116 {
85 if (mimeType.Find(L"image/") >= 0) 117 if (mimeType.Find(L"image/") >= 0)
86 { 118 {
87 return ContentType::CONTENT_TYPE_IMAGE; 119 return ContentType::CONTENT_TYPE_IMAGE;
88 } 120 }
89 if (mimeType.Find(L"text/css") >= 0) 121 if (mimeType.Find(L"text/css") >= 0)
(...skipping 14 matching lines...) Expand all
104 } 136 }
105 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example 137 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example
106 if (mimeType.Find(L"xml") >= 0) 138 if (mimeType.Find(L"xml") >= 0)
107 { 139 {
108 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; 140 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
109 } 141 }
110 142
111 return ContentType::CONTENT_TYPE_OTHER; 143 return ContentType::CONTENT_TYPE_OTHER;
112 } 144 }
113 145
114 ContentType WBPassthruSink::GetContentTypeFromURL(const CString& src) 146 ContentType WBPassthruSink::GetContentTypeFromURL(const std::wstring& src)
115 { 147 {
116 CString srcExt = src; 148 CString srcLegacy = ToCString(src);
149 CString srcExt = srcLegacy;
117 150
118 int pos = 0; 151 int pos = 0;
119 if ((pos = src.Find('?')) > 0) 152 if ((pos = srcLegacy.Find('?')) > 0)
120 { 153 {
121 srcExt = src.Left(pos); 154 srcExt = srcLegacy.Left(pos);
122 } 155 }
123 156
124 int lastDotIndex = srcExt.ReverseFind('.'); 157 int lastDotIndex = srcExt.ReverseFind('.');
125 if (lastDotIndex < 0) 158 if (lastDotIndex < 0)
126 return ContentType::CONTENT_TYPE_OTHER; 159 return ContentType::CONTENT_TYPE_OTHER;
127 CString ext = srcExt.Mid(lastDotIndex); 160 CString ext = srcExt.Mid(lastDotIndex);
128 if (ext == L".jpg" || ext == L".gif" || ext == L".png" || ext == L".jpeg") 161 if (ext == L".jpg" || ext == L".gif" || ext == L".png" || ext == L".jpeg")
129 { 162 {
130 return ContentType::CONTENT_TYPE_IMAGE; 163 return ContentType::CONTENT_TYPE_IMAGE;
131 } 164 }
(...skipping 13 matching lines...) Expand all
145 { 178 {
146 return ContentType::CONTENT_TYPE_OBJECT; 179 return ContentType::CONTENT_TYPE_OBJECT;
147 } 180 }
148 else if (ext == L".jsp" || ext == L".php" || ext == L".html") 181 else if (ext == L".jsp" || ext == L".php" || ext == L".html")
149 { 182 {
150 return ContentType::CONTENT_TYPE_SUBDOCUMENT; 183 return ContentType::CONTENT_TYPE_SUBDOCUMENT;
151 } 184 }
152 return ContentType::CONTENT_TYPE_OTHER; 185 return ContentType::CONTENT_TYPE_OTHER;
153 } 186 }
154 187
155 ContentType WBPassthruSink::GetContentType(const CString& mimeType, const std::w string& domain, const CString& src) 188 ContentType WBPassthruSink::GetContentType(const CString& mimeType, const std::w string& domain, const std::wstring& src)
156 { 189 {
157 // No referer or mime type 190 // No referer or mime type
158 // BINDSTRING_XDR_ORIGIN works only for IE v8+ 191 // BINDSTRING_XDR_ORIGIN works only for IE v8+
159 if (mimeType.IsEmpty() && domain.empty() && CPluginClient::GetInstance()->GetI EVersion() >= 8) 192 if (mimeType.IsEmpty() && domain.empty() && AdblockPlus::IE::InstalledMajorVer sion() >= 8)
160 { 193 {
161 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; 194 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
162 } 195 }
163 int contentType = GetContentTypeFromMimeType(mimeType); 196 ContentType contentType = GetContentTypeFromMimeType(mimeType);
164 if (contentType == ContentType::CONTENT_TYPE_OTHER) 197 if (contentType == ContentType::CONTENT_TYPE_OTHER)
165 { 198 {
166 contentType = GetContentTypeFromURL(src); 199 contentType = GetContentTypeFromURL(src);
167 } 200 }
168 return ContentType::CONTENT_TYPE_OTHER; 201 return contentType;
169 } 202 }
170 203
171 //////////////////////////////////////////////////////////////////////////////// //////// 204 //////////////////////////////////////////////////////////////////////////////// ////////
172 //WBPassthruSink 205 //WBPassthruSink
173 //Monitor and/or cancel every request and responde 206 //Monitor and/or cancel every request and responde
174 //WB makes, including images, sounds, scripts, etc 207 //WB makes, including images, sounds, scripts, etc
175 //////////////////////////////////////////////////////////////////////////////// //////// 208 //////////////////////////////////////////////////////////////////////////////// ////////
176 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, 209 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k,
177 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, 210 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved,
178 IInternetProtocol* pTargetProtocol, bool& handle d) 211 IInternetProtocol* pTargetProtocol, bool& handle d)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 return false; 307 return false;
275 } 308 }
276 309
277 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) 310 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
278 { 311 {
279 if (!szURL) 312 if (!szURL)
280 { 313 {
281 return E_POINTER; 314 return E_POINTER;
282 } 315 }
283 std::wstring src = szURL; 316 std::wstring src = szURL;
317 UnescapeUrl(src);
284 DEBUG_GENERAL(ToCString(src)); 318 DEBUG_GENERAL(ToCString(src));
285 319
286 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol); 320 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol);
287 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str())) ;
288 321
289 if (pszAdditionalHeaders) 322 if (pszAdditionalHeaders)
290 { 323 {
291 *pszAdditionalHeaders = nullptr; 324 *pszAdditionalHeaders = nullptr;
292 } 325 }
293 326
294 CComPtr<IHttpNegotiate> httpNegotiate; 327 CComPtr<IHttpNegotiate> httpNegotiate;
295 QueryServiceFromClient(&httpNegotiate); 328 QueryServiceFromClient(&httpNegotiate);
296 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need. 329 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need.
297 // There doesn't seem to be any other way to get this header before the reques t has been made. 330 // There doesn't seem to be any other way to get this header before the reques t has been made.
298 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; 331 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK;
299 332
300 if (pszAdditionalHeaders && *pszAdditionalHeaders) 333 if (pszAdditionalHeaders && *pszAdditionalHeaders)
301 { 334 {
302 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n"); 335 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n");
303 } 336 }
304 m_boundDomain = TrimString(m_boundDomain); 337 m_boundDomain = TrimString(m_boundDomain);
338 m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDoma in, src);
339
305 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); 340 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
306 CPluginClient* client = CPluginClient::GetInstance(); 341 CPluginClient* client = CPluginClient::GetInstance();
307 342
308 if (tab && client) 343 if (tab && client)
309 { 344 {
310 CString documentUrl = tab->GetDocumentUrl(); 345 std::wstring documentUrl = tab->GetDocumentUrl();
311 // Page is identical to document => don't block 346 // Page is identical to document => don't block
312 if (documentUrl == ToCString(src)) 347 if (documentUrl == src)
313 { 348 {
314 return nativeHr; 349 return nativeHr;
315 } 350 }
316 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl))) 351 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(documentUrl))
317 { 352 {
318 if (tab->IsFrameCached(ToCString(src))) 353 if (tab->IsFrameCached(src))
319 { 354 {
320 m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT; 355 m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT;
321 } 356 }
322 } 357 }
323 } 358 }
324 359
325 if (IsFlashRequest(pszAdditionalHeaders)) 360 if (IsFlashRequest(pszAdditionalHeaders))
326 { 361 {
327 m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST; 362 m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST;
328 } 363 }
329 364
330 if (pszAdditionalHeaders && IsXmlHttpRequest(*pszAdditionalHeaders)) 365 if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi tionalHeaders))
331 { 366 {
332 m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST; 367 m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
333 } 368 }
334 369
335 m_blockedInTransaction = client->ShouldBlock(szURL, m_contentType, m_boundDoma in); 370 if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but must be set*/true))
336 if (m_blockedInTransaction) 371 {
337 { 372 // NOTE: Feeding custom HTML to Flash, instead of original object subrequest
373 // doesn't have much sense. It also can manifest in unwanted result
374 // like video being blocked (See https://issues.adblockplus.org/ticket/1669)
375 // So we report blocked object subrequests as failed, not just empty HTML.
376 m_isCustomResponse = m_contentType != ContentType::CONTENT_TYPE_OBJECT_SUBRE QUEST;
338 return E_ABORT; 377 return E_ABORT;
339 } 378 }
340 return nativeHr; 379 return nativeHr;
341 } 380 }
342 381
343 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) 382 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
344 { 383 {
345 if (pszAdditionalRequestHeaders) 384 if (pszAdditionalRequestHeaders)
346 { 385 {
347 *pszAdditionalRequestHeaders = 0; 386 *pszAdditionalRequestHeaders = 0;
348 } 387 }
349 388
350 CComPtr<IHttpNegotiate> spHttpNegotiate; 389 CComPtr<IHttpNegotiate> spHttpNegotiate;
351 QueryServiceFromClient(&spHttpNegotiate); 390 QueryServiceFromClient(&spHttpNegotiate);
352 391
353 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; 392 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK;
354 } 393 }
355 394
356 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus Text) 395 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus Text)
357 { 396 {
358 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS tatusCode, szStatusText) : S_OK; 397 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS tatusCode, szStatusText) : S_OK;
359 } 398 }
360 399
361 STDMETHODIMP WBPassthruSink::ReportResult(/* [in] */ HRESULT hrResult, /* [in] * / DWORD dwError, /* [in] */ LPCWSTR szResult) 400 STDMETHODIMP WBPassthruSink::ReportResult(/* [in] */ HRESULT hrResult, /* [in] * / DWORD dwError, /* [in] */ LPCWSTR szResult)
362 { 401 {
363 if (m_blockedInTransaction) 402 if (m_isCustomResponse)
364 { 403 {
365 // Don't notify the client about aborting of the operation, thus don't call BaseClass::ReportResult. 404 // Don't notify the client about aborting of the operation, thus don't call BaseClass::ReportResult.
366 // Current method is called by the original protocol implementation and we a re intercepting the 405 // Current method is called by the original protocol implementation and we a re intercepting the
367 // call here and eating it, we will call the proper ReportResult later by ou rself. 406 // call here and eating it, we will call the proper ReportResult later by ou rself.
368 return S_OK; 407 return S_OK;
369 } 408 }
370 return BaseClass::ReportResult(hrResult, dwError, szResult); 409 return BaseClass::ReportResult(hrResult, dwError, szResult);
371 } 410 }
372 411
373 412
(...skipping 12 matching lines...) Expand all
386 } 425 }
387 426
388 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol); 427 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol);
389 } 428 }
390 429
391 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead) 430 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead)
392 { 431 {
393 WBPassthruSink* pSink = GetSink(); 432 WBPassthruSink* pSink = GetSink();
394 return pSink->OnRead(pv, cb, pcbRead); 433 return pSink->OnRead(pv, cb, pcbRead);
395 } 434 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld