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

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

Issue 6216090891845632: Issue #404 - Create common library shared between plugin/engine and installer (Closed)
Left Patch Set: Created Jan. 9, 2015, 8:07 p.m.
Right Patch Set: final check after rebase Created May 19, 2015, 3:36 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/PluginTabBase.cpp ('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"
13 #include "IE_Version.h" 30 #include "IeVersion.h"
14 31
15 namespace 32 namespace
16 { 33 {
17 const std::string g_blockedByABPPage = "<!DOCTYPE html>" 34 const std::string g_blockedByABPPage = "<!DOCTYPE html>"
18 "<html>" 35 "<html>"
19 "<body>" 36 "<body>"
20 "<!-- blocked by AdblockPlus -->" 37 "<!-- blocked by AdblockPlus -->"
21 "</body>" 38 "</body>"
22 "</html>"; 39 "</html>";
23 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
54 typedef AdblockPlus::FilterEngine::ContentType ContentType;
55
24 template <class T> 56 template <class T>
25 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)
26 { 58 {
27 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon); 59 const T allHeadersLower = ASCIIStringToLower(allHeaders);
60 auto targetHeaderBeginsAt = allHeadersLower.find(ASCIIStringToLower(targetHe aderNameWithColon));
28 if (targetHeaderBeginsAt == T::npos) 61 if (targetHeaderBeginsAt == T::npos)
29 { 62 {
30 return T(); 63 return T();
31 } 64 }
32 targetHeaderBeginsAt += targetHeaderNameWithColon.length(); 65 targetHeaderBeginsAt += targetHeaderNameWithColon.length();
33 auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt); 66 auto targetHeaderEndsAt = allHeadersLower.find(ASCIIStringToLower(delimiter) , targetHeaderBeginsAt);
34 if (targetHeaderEndsAt == T::npos) 67 if (targetHeaderEndsAt == T::npos)
35 { 68 {
36 return T(); 69 return T();
37 } 70 }
38 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHe aderBeginsAt); 71 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHe aderBeginsAt);
39 } 72 }
40 73
41 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol) 74 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol)
42 { 75 {
43 // 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 19 matching lines...) Expand all
63 return ""; 96 return "";
64 } 97 }
65 return ExtractHttpHeader<std::string>(buf, "Accept:", "\r\n"); 98 return ExtractHttpHeader<std::string>(buf, "Accept:", "\r\n");
66 } 99 }
67 100
68 bool IsXmlHttpRequest(const std::wstring& additionalHeaders) 101 bool IsXmlHttpRequest(const std::wstring& additionalHeaders)
69 { 102 {
70 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");
71 return TrimString(requestedWithHeader) == L"XMLHttpRequest"; 104 return TrimString(requestedWithHeader) == L"XMLHttpRequest";
72 } 105 }
106
107 ContentType GetContentTypeFromString(const std::wstring& value)
108 {
109 auto lastDotPos = value.rfind(L'.');
110 if (lastDotPos == std::wstring::npos)
111 return ContentType::CONTENT_TYPE_OTHER;
112
113 std::wstring ext = ASCIIStringToLower(value.substr(lastDotPos + 1));
114 if (ext == L"jpg" || ext == L"gif" || ext == L"png" || ext == L"jpeg")
115 {
116 return ContentType::CONTENT_TYPE_IMAGE;
117 }
118 else if (ext == L"css")
119 {
120 return ContentType::CONTENT_TYPE_STYLESHEET;
121 }
122 else if (ext == L"js")
123 {
124 return ContentType::CONTENT_TYPE_SCRIPT;
125 }
126 else if (ext == L"xml")
127 {
128 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
129 }
130 else if (ext == L"swf")
131 {
132 return ContentType::CONTENT_TYPE_OBJECT;
133 }
134 else if (ext == L"jsp" || ext == L"php" || ext == L"html")
135 {
136 return ContentType::CONTENT_TYPE_SUBDOCUMENT;
137 }
138 return ContentType::CONTENT_TYPE_OTHER;
139 }
73 } 140 }
74 141
75 WBPassthruSink::WBPassthruSink() 142 WBPassthruSink::WBPassthruSink()
76 : m_currentPositionOfSentPage(0) 143 : m_currentPositionOfSentPage(0)
77 , m_contentType(CFilter::EContentType::contentTypeAny) 144 , m_contentType(ContentType::CONTENT_TYPE_OTHER)
78 , m_isCustomResponse(false) 145 , m_isCustomResponse(false)
79 { 146 {
80 } 147 }
81 148
82 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) 149 ContentType WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType)
83 { 150 {
84 if (mimeType.Find(L"image/") >= 0) 151 if (mimeType.Find(L"image/") >= 0)
85 { 152 {
86 return CFilter::contentTypeImage; 153 return ContentType::CONTENT_TYPE_IMAGE;
87 } 154 }
88 if (mimeType.Find(L"text/css") >= 0) 155 if (mimeType.Find(L"text/css") >= 0)
89 { 156 {
90 return CFilter::contentTypeStyleSheet; 157 return ContentType::CONTENT_TYPE_STYLESHEET;
91 } 158 }
92 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0)) 159 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0))
93 { 160 {
94 return CFilter::contentTypeScript; 161 return ContentType::CONTENT_TYPE_SCRIPT;
95 } 162 }
96 if (mimeType.Find(L"application/x-shockwave-flash") >= 0) 163 if (mimeType.Find(L"application/x-shockwave-flash") >= 0)
97 { 164 {
98 return CFilter::contentTypeObject; 165 return ContentType::CONTENT_TYPE_OBJECT;
99 } 166 }
100 if (mimeType.Find(L"text/html") >= 0) 167 if (mimeType.Find(L"text/html") >= 0)
101 { 168 {
102 return CFilter::contentTypeSubdocument; 169 return ContentType::CONTENT_TYPE_SUBDOCUMENT;
103 } 170 }
104 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example 171 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example
105 if (mimeType.Find(L"xml") >= 0) 172 if (mimeType.Find(L"xml") >= 0)
106 { 173 {
107 return CFilter::contentTypeXmlHttpRequest; 174 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
108 } 175 }
109 176
110 return CFilter::contentTypeAny; 177 return ContentType::CONTENT_TYPE_OTHER;
111 } 178 }
112 179
113 int WBPassthruSink::GetContentTypeFromURL(const CString& src) 180 ContentType WBPassthruSink::GetContentTypeFromURL(const std::wstring& src)
114 { 181 {
115 CString srcExt = src; 182 std::wstring schemeAndHierarchicalPart = GetSchemeAndHierarchicalPart(src);
116 183 auto contentType = GetContentTypeFromString(schemeAndHierarchicalPart);
117 int pos = 0; 184 if (contentType == ContentType::CONTENT_TYPE_OTHER &&
118 if ((pos = src.Find('?')) > 0) 185 AdblockPlus::IE::InstalledMajorVersion() == 8)
119 { 186 {
120 srcExt = src.Left(pos); 187 std::wstring queryString = GetQueryString(src);
121 } 188 wchar_t* nextToken = nullptr;
122 189 const wchar_t* token = wcstok_s(&queryString[0], L"&=", &nextToken);
123 int lastDotIndex = srcExt.ReverseFind('.'); 190 while (token != nullptr)
124 if (lastDotIndex < 0) 191 {
125 return CFilter::contentTypeAny; 192 contentType = GetContentTypeFromString(token);
126 CString ext = srcExt.Mid(lastDotIndex); 193 if (contentType != ContentType::CONTENT_TYPE_OTHER)
127 if (ext == L".jpg" || ext == L".gif" || ext == L".png" || ext == L".jpeg") 194 {
128 { 195 return contentType;
129 return CFilter::contentTypeImage; 196 }
130 } 197 token = wcstok_s(nullptr, L"&=", &nextToken);
131 else if (ext == L".css") 198 }
132 { 199 }
133 return CFilter::contentTypeStyleSheet; 200 return contentType;
134 } 201 }
135 else if (ext.Right(3) == L".js") 202
136 { 203 ContentType WBPassthruSink::GetContentType(const CString& mimeType, const std::w string& domain, const std::wstring& src)
137 return CFilter::contentTypeScript;
138 }
139 else if (ext == L".xml")
140 {
141 return CFilter::contentTypeXmlHttpRequest;
142 }
143 else if (ext == L".swf")
144 {
145 return CFilter::contentTypeObject;
146 }
147 else if (ext == L".jsp" || ext == L".php" || ext == L".html")
148 {
149 return CFilter::contentTypeSubdocument;
150 }
151 return CFilter::contentTypeAny;
152 }
153
154 int WBPassthruSink::GetContentType(const CString& mimeType, const std::wstring& domain, const CString& src)
155 { 204 {
156 // No referer or mime type 205 // No referer or mime type
157 // BINDSTRING_XDR_ORIGIN works only for IE v8+ 206 // BINDSTRING_XDR_ORIGIN works only for IE v8+
158 if (mimeType.IsEmpty() && domain.empty() && AdblockPlus::IE::InstalledMajorVer sion() >= 8) 207 if (mimeType.IsEmpty() && domain.empty() && AdblockPlus::IE::InstalledMajorVer sion() >= 8)
159 { 208 {
160 return CFilter::contentTypeXmlHttpRequest; 209 return ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
161 } 210 }
162 int contentType = GetContentTypeFromMimeType(mimeType); 211 ContentType contentType = GetContentTypeFromMimeType(mimeType);
163 if (contentType == CFilter::contentTypeAny) 212 if (contentType == ContentType::CONTENT_TYPE_OTHER)
164 { 213 {
165 contentType = GetContentTypeFromURL(src); 214 contentType = GetContentTypeFromURL(src);
166 } 215 }
167 return contentType; 216 return contentType;
168 } 217 }
169 218
170 //////////////////////////////////////////////////////////////////////////////// //////// 219 //////////////////////////////////////////////////////////////////////////////// ////////
171 //WBPassthruSink 220 //WBPassthruSink
172 //Monitor and/or cancel every request and responde 221 //Monitor and/or cancel every request and responde
173 //WB makes, including images, sounds, scripts, etc 222 //WB makes, including images, sounds, scripts, etc
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 return false; 322 return false;
274 } 323 }
275 324
276 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) 325 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
277 { 326 {
278 if (!szURL) 327 if (!szURL)
279 { 328 {
280 return E_POINTER; 329 return E_POINTER;
281 } 330 }
282 std::wstring src = szURL; 331 std::wstring src = szURL;
283 DEBUG_GENERAL(ToCString(src)); 332 UnescapeUrl(src);
333 DEBUG_GENERAL(src);
284 334
285 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol); 335 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol);
286 336
287 if (pszAdditionalHeaders) 337 if (pszAdditionalHeaders)
288 { 338 {
289 *pszAdditionalHeaders = nullptr; 339 *pszAdditionalHeaders = nullptr;
290 } 340 }
291 341
292 CComPtr<IHttpNegotiate> httpNegotiate; 342 CComPtr<IHttpNegotiate> httpNegotiate;
293 QueryServiceFromClient(&httpNegotiate); 343 QueryServiceFromClient(&httpNegotiate);
294 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need. 344 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need.
295 // There doesn't seem to be any other way to get this header before the reques t has been made. 345 // There doesn't seem to be any other way to get this header before the reques t has been made.
296 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; 346 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK;
297 347
298 if (pszAdditionalHeaders && *pszAdditionalHeaders) 348 if (pszAdditionalHeaders && *pszAdditionalHeaders)
299 { 349 {
300 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n"); 350 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n");
301 } 351 }
302 m_boundDomain = TrimString(m_boundDomain); 352 m_boundDomain = TrimString(m_boundDomain);
303 m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDoma in, ToCString(src)); 353 m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDoma in, src);
354
304 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); 355 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
305 CPluginClient* client = CPluginClient::GetInstance(); 356 CPluginClient* client = CPluginClient::GetInstance();
306 357
307 if (tab && client) 358 if (tab && client)
308 { 359 {
309 CString documentUrl = tab->GetDocumentUrl(); 360 std::wstring documentUrl = tab->GetDocumentUrl();
310 // Page is identical to document => don't block 361 // Page is identical to document => don't block
311 if (documentUrl == ToCString(src)) 362 if (documentUrl == src)
312 { 363 {
313 return nativeHr; 364 return nativeHr;
314 } 365 }
315 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl))) 366 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(documentUrl))
316 { 367 {
317 if (tab->IsFrameCached(ToCString(src))) 368 if (tab->IsFrameCached(src))
318 { 369 {
319 m_contentType = CFilter::contentTypeSubdocument; 370 m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT;
320 } 371 }
321 } 372 }
322 } 373 }
323 374
324 if (IsFlashRequest(pszAdditionalHeaders)) 375 if (IsFlashRequest(pszAdditionalHeaders))
325 { 376 {
326 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; 377 m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST;
327 } 378 }
328 379
329 if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi tionalHeaders)) 380 if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi tionalHeaders))
330 { 381 {
331 m_contentType = CFilter::EContentType::contentTypeXmlHttpRequest; 382 m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST;
332 } 383 }
333 384
334 if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but must be set*/true)) 385 if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but must be set*/true))
335 { 386 {
336 // NOTE: Feeding custom HTML to Flash, instead of original object subrequest 387 // NOTE: Feeding custom HTML to Flash, instead of original object subrequest
337 // doesn't have much sense. It also can manifest in unwanted result» 388 // doesn't have much sense. It also can manifest in unwanted result
338 // like video being blocked (See https://issues.adblockplus.org/ticket/1669) » 389 // like video being blocked (See https://issues.adblockplus.org/ticket/1669)
339 // So we report blocked object subrequests as failed, not just empty HTML. 390 // So we report blocked object subrequests as failed, not just empty HTML.
340 m_isCustomResponse = m_contentType != CFilter::contentTypeObjectSubrequest; 391 m_isCustomResponse = m_contentType != ContentType::CONTENT_TYPE_OBJECT_SUBRE QUEST;
341 return E_ABORT; 392 return E_ABORT;
342 } 393 }
343 return nativeHr; 394 return nativeHr;
344 } 395 }
345 396
346 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) 397 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
347 { 398 {
348 if (pszAdditionalRequestHeaders) 399 if (pszAdditionalRequestHeaders)
349 { 400 {
350 *pszAdditionalRequestHeaders = 0; 401 *pszAdditionalRequestHeaders = 0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 440 }
390 441
391 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol); 442 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol);
392 } 443 }
393 444
394 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead) 445 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead)
395 { 446 {
396 WBPassthruSink* pSink = GetSink(); 447 WBPassthruSink* pSink = GetSink();
397 return pSink->OnRead(pv, cb, pcbRead); 448 return pSink->OnRead(pv, cb, pcbRead);
398 } 449 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld