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

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

Issue 5506777797885952: Issue 1530 - Improve detecting of subrequest issued by flash addon (Closed)
Patch Set: Created Nov. 12, 2014, 8:13 a.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') | no next file » | 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 #include "PluginFilter.h" 6 #include "PluginFilter.h"
7 #include "PluginSettings.h" 7 #include "PluginSettings.h"
8 #include "PluginClass.h" 8 #include "PluginClass.h"
9 #include "PluginSystem.h" 9 #include "PluginSystem.h"
10 #include <WinInet.h> 10 #include <WinInet.h>
11 #include "wtypes.h" 11 #include "wtypes.h"
12 #include "../shared/Utils.h" 12 #include "../shared/Utils.h"
13 13
14 namespace 14 namespace
15 { 15 {
16 std::string g_blockedByABPPage = "<!DOCTYPE html>" 16 const std::string g_blockedByABPPage = "<!DOCTYPE html>"
Oleksandr 2014/11/13 04:44:42 Unrelated change
sergei 2014/11/13 08:49:32 removed from here
17 "<html>" 17 "<html>"
18 "<body>" 18 "<body>"
19 "<!-- blocked by AdblockPlus -->" 19 "<!-- blocked by AdblockPlus -->"
20 "</body>" 20 "</body>"
21 "</html>"; 21 "</html>";
22 22
23 template <class T> 23 template <class T>
24 T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c onst T& delimiter) 24 std::pair<T, bool> ExtractHttpHeader(const T& allHeaders, const T& targetHeade rNameWithColon, const T& delimiter)
Oleksandr 2014/11/13 04:44:42 Unrelated change. Also, I think was good enough as
sergei 2014/11/13 08:49:32 Right, it's not necessary. Reverted.
25 { 25 {
26 std::pair<T, bool> notFoundHeader;
26 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon); 27 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon);
27 if (targetHeaderBeginsAt == T::npos) 28 if (targetHeaderBeginsAt == T::npos)
28 { 29 {
29 return T(); 30 return notFoundHeader;
30 } 31 }
31 targetHeaderBeginsAt += targetHeaderNameWithColon.length(); 32 targetHeaderBeginsAt += targetHeaderNameWithColon.length();
32 auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt); 33 auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt);
33 if (targetHeaderEndsAt == T::npos) 34 if (targetHeaderEndsAt == T::npos)
34 { 35 {
35 return T(); 36 return notFoundHeader;
36 } 37 }
37 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHe aderBeginsAt); 38 return std::make_pair(allHeaders.substr(targetHeaderBeginsAt, targetHeaderEn dsAt - targetHeaderBeginsAt), true);
38 } 39 }
39 40
40 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol) 41 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol)
41 { 42 {
42 // Despite there being HTTP_QUERY_ACCEPT and other query info flags, they do n't work here, 43 // Despite there being HTTP_QUERY_ACCEPT and other query info flags, they do n't work here,
43 // only HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS does w ork. 44 // only HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS does w ork.
44 ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo; 45 ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo;
45 HRESULT hr = internetProtocol->QueryInterface(&winInetHttpInfo); 46 HRESULT hr = internetProtocol->QueryInterface(&winInetHttpInfo);
46 if (FAILED(hr)) 47 if (FAILED(hr))
47 { 48 {
48 return ""; 49 return "";
49 } 50 }
50 DWORD size = 0; 51 DWORD size = 0;
51 DWORD flags = 0; 52 DWORD flags = 0;
52 DWORD queryOption = HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HE ADERS; 53 DWORD queryOption = HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HE ADERS;
53 hr = winInetHttpInfo->QueryInfo(queryOption, /*buffer*/ nullptr, /*get size* / &size, &flags, /*reserved*/ 0); 54 hr = winInetHttpInfo->QueryInfo(queryOption, /*buffer*/ nullptr, /*get size* / &size, &flags, /*reserved*/ 0);
54 if (FAILED(hr)) 55 if (FAILED(hr))
55 { 56 {
56 return ""; 57 return "";
57 } 58 }
58 std::string buf(size, '\0'); 59 std::string buf(size, '\0');
59 hr = winInetHttpInfo->QueryInfo(queryOption, &buf[0], &size, &flags, 0); 60 hr = winInetHttpInfo->QueryInfo(queryOption, &buf[0], &size, &flags, 0);
60 if (FAILED(hr)) 61 if (FAILED(hr))
61 { 62 {
62 return ""; 63 return "";
63 } 64 }
64 return ExtractHttpHeader<std::string>(buf, "Accept:", "\r\n"); 65 auto acceptHeader = ExtractHttpHeader<std::string>(buf, "Accept:", "\r\n");
66 return acceptHeader.first;
67 }
68
69 bool IsXmlHttpRequest(const std::wstring& additionalHeaders)
70 {
71 auto requestedWithHeader = ExtractHttpHeader<std::wstring>(additionalHeaders , L"X-Requested-With: ", L"\n");
Oleksandr 2014/11/13 04:44:42 X-Requested-With is only part of the story, I thin
72 return requestedWithHeader.second && TrimString(requestedWithHeader.first) = = L"XMLHttpRequest";
65 } 73 }
66 } 74 }
67 75
68 WBPassthruSink::WBPassthruSink() 76 WBPassthruSink::WBPassthruSink()
69 : m_currentPositionOfSentPage(0) 77 : m_currentPositionOfSentPage(0)
70 , m_contentType(CFilter::EContentType::contentTypeAny) 78 , m_contentType(CFilter::EContentType::contentTypeAny)
71 , m_blockedInTransaction(false) 79 , m_blockedInTransaction(false)
72 { 80 {
73 } 81 }
74 82
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 " 244 "
237 */ 245 */
238 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED; 246 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED;
239 } 247 }
240 248
241 // This is the heuristic which detects the requests issued by Flash.ocx. 249 // This is the heuristic which detects the requests issued by Flash.ocx.
242 // It turned out that the implementation from ''Flash.ocx'' (tested version is 1 5.0.0.152) 250 // It turned out that the implementation from ''Flash.ocx'' (tested version is 1 5.0.0.152)
243 // returns quite minimal configuration in comparison with the implementation fro m Microsofts' 251 // returns quite minimal configuration in comparison with the implementation fro m Microsofts'
244 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often inclu des something 252 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often inclu des something
245 // else. 253 // else.
246 bool WBPassthruSink::IsFlashRequest() 254 bool WBPassthruSink::IsFlashRequest(const wchar_t* const* additionalHeaders)
247 { 255 {
256 if (additionalHeaders && *additionalHeaders)
257 {
258 auto flashVersionHeader = ExtractHttpHeader<std::wstring>(*additionalHeaders , L"x-flash-version: ", L"\n");
259 if (flashVersionHeader.second)
260 {
261 return true;
262 }
263 }
248 ATL::CComPtr<IBindStatusCallback> bscb; 264 ATL::CComPtr<IBindStatusCallback> bscb;
249 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb) 265 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb)
250 { 266 {
251 DWORD grfBINDF = 0; 267 DWORD grfBINDF = 0;
252 BINDINFO bindInfo = {}; 268 BINDINFO bindInfo = {};
253 bindInfo.cbSize = sizeof(bindInfo); 269 bindInfo.cbSize = sizeof(bindInfo);
254 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) && 270 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) &&
255 (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF && 271 (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF &&
256 (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindI nfo.dwOptions 272 (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindI nfo.dwOptions
257 ) 273 )
258 { 274 {
259 return true; 275 return true;
260 } 276 }
261 } 277 }
262 return false; 278 return false;
263 } 279 }
264 280
265 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) 281 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
266 { 282 {
283 if (!szURL || !szHeaders)
284 {
285 return E_POINTER;
286 }
Oleksandr 2014/11/13 04:44:42 Unrelated change.
sergei 2014/11/13 08:49:32 Removed from here.
267 std::wstring src = szURL; 287 std::wstring src = szURL;
268 DEBUG_GENERAL(ToCString(src)); 288 DEBUG_GENERAL(ToCString(src));
269 289
270 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol); 290 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol);
271 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str())) ; 291 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str())) ;
272 292
273 if (pszAdditionalHeaders) 293 if (pszAdditionalHeaders)
274 { 294 {
275 *pszAdditionalHeaders = nullptr; 295 *pszAdditionalHeaders = nullptr;
276 } 296 }
277 297
278 CComPtr<IHttpNegotiate> httpNegotiate; 298 CComPtr<IHttpNegotiate> httpNegotiate;
279 QueryServiceFromClient(&httpNegotiate); 299 QueryServiceFromClient(&httpNegotiate);
280 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need. 300 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need.
281 // There doesn't seem to be any other way to get this header before the reques t has been made. 301 // There doesn't seem to be any other way to get this header before the reques t has been made.
282 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; 302 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK;
283 303
284 if (*pszAdditionalHeaders != 0) 304 if (pszAdditionalHeaders && *pszAdditionalHeaders)
285 { 305 {
286 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n").c_str(); 306 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n").first;
287 } 307 }
288 m_boundDomain = TrimString(m_boundDomain); 308 m_boundDomain = TrimString(m_boundDomain);
289 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); 309 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
290 CPluginClient* client = CPluginClient::GetInstance(); 310 CPluginClient* client = CPluginClient::GetInstance();
291 311
292 if (tab && client) 312 if (tab && client)
293 { 313 {
294 CString documentUrl = tab->GetDocumentUrl(); 314 CString documentUrl = tab->GetDocumentUrl();
295 // Page is identical to document => don't block 315 // Page is identical to document => don't block
296 if (documentUrl == ToCString(src)) 316 if (documentUrl == ToCString(src))
297 { 317 {
298 return nativeHr; 318 return nativeHr;
299 } 319 }
300 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl))) 320 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl)))
301 { 321 {
302 if (tab->IsFrameCached(ToCString(src))) 322 if (tab->IsFrameCached(ToCString(src)))
303 { 323 {
304 m_contentType = CFilter::contentTypeSubdocument; 324 m_contentType = CFilter::contentTypeSubdocument;
305 } 325 }
306 } 326 }
307 } 327 }
308 328
309 if (IsFlashRequest()) 329 if (IsFlashRequest(pszAdditionalHeaders))
310 { 330 {
311 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; 331 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest;
332 }
333
334 if (pszAdditionalHeaders && IsXmlHttpRequest(*pszAdditionalHeaders))
335 {
336 m_contentType = CFilter::EContentType::contentTypeXmlHttpRequest;
312 } 337 }
313 338
314 m_blockedInTransaction = client->ShouldBlock(szURL, m_contentType, m_boundDoma in, /*debug flag but must be set*/true); 339 m_blockedInTransaction = client->ShouldBlock(szURL, m_contentType, m_boundDoma in, /*debug flag but must be set*/true);
315 if (m_blockedInTransaction) 340 if (m_blockedInTransaction)
316 { 341 {
317 return E_ABORT; 342 return E_ABORT;
318 } 343 }
319 return nativeHr; 344 return nativeHr;
320 } 345 }
321 346
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 400
376 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) 401 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options)
377 { 402 {
378 return BaseClass::LockRequest(options); 403 return BaseClass::LockRequest(options);
379 } 404 }
380 405
381 STDMETHODIMP WBPassthru::UnlockRequest() 406 STDMETHODIMP WBPassthru::UnlockRequest()
382 { 407 {
383 return BaseClass::UnlockRequest(); 408 return BaseClass::UnlockRequest();
384 } 409 }
OLDNEW
« no previous file with comments | « src/plugin/PluginWbPassThrough.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld