| OLD | NEW | 
|---|
| 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-2015 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 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 31 | 31 | 
| 32 namespace | 32 namespace | 
| 33 { | 33 { | 
| 34   const std::string g_blockedByABPPage = "<!DOCTYPE html>" | 34   const std::string g_blockedByABPPage = "<!DOCTYPE html>" | 
| 35     "<html>" | 35     "<html>" | 
| 36         "<body>" | 36         "<body>" | 
| 37           "<!-- blocked by AdblockPlus -->" | 37           "<!-- blocked by AdblockPlus -->" | 
| 38         "</body>" | 38         "</body>" | 
| 39     "</html>"; | 39     "</html>"; | 
| 40 | 40 | 
|  | 41   typedef AdblockPlus::FilterEngine::ContentType ContentType; | 
|  | 42 | 
| 41   template <class T> | 43   template <class T> | 
| 42   T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c
     onst T& delimiter) | 44   T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c
     onst T& delimiter) | 
| 43   { | 45   { | 
| 44     auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon); | 46     auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon); | 
| 45     if (targetHeaderBeginsAt == T::npos) | 47     if (targetHeaderBeginsAt == T::npos) | 
| 46     { | 48     { | 
| 47       return T(); | 49       return T(); | 
| 48     } | 50     } | 
| 49     targetHeaderBeginsAt += targetHeaderNameWithColon.length(); | 51     targetHeaderBeginsAt += targetHeaderNameWithColon.length(); | 
| 50     auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt); | 52     auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 84 | 86 | 
| 85   bool IsXmlHttpRequest(const std::wstring& additionalHeaders) | 87   bool IsXmlHttpRequest(const std::wstring& additionalHeaders) | 
| 86   { | 88   { | 
| 87     auto requestedWithHeader = ExtractHttpHeader<std::wstring>(additionalHeaders
     , L"X-Requested-With:", L"\n"); | 89     auto requestedWithHeader = ExtractHttpHeader<std::wstring>(additionalHeaders
     , L"X-Requested-With:", L"\n"); | 
| 88     return TrimString(requestedWithHeader) == L"XMLHttpRequest"; | 90     return TrimString(requestedWithHeader) == L"XMLHttpRequest"; | 
| 89   } | 91   } | 
| 90 } | 92 } | 
| 91 | 93 | 
| 92 WBPassthruSink::WBPassthruSink() | 94 WBPassthruSink::WBPassthruSink() | 
| 93   : m_currentPositionOfSentPage(0) | 95   : m_currentPositionOfSentPage(0) | 
| 94   , m_contentType(CFilter::EContentType::contentTypeAny) | 96   , m_contentType(ContentType::CONTENT_TYPE_OTHER) | 
| 95   , m_isCustomResponse(false) | 97   , m_isCustomResponse(false) | 
| 96 { | 98 { | 
| 97 } | 99 } | 
| 98 | 100 | 
| 99 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) | 101 ContentType WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) | 
| 100 { | 102 { | 
| 101   if (mimeType.Find(L"image/") >= 0) | 103   if (mimeType.Find(L"image/") >= 0) | 
| 102   { | 104   { | 
| 103     return CFilter::contentTypeImage; | 105     return ContentType::CONTENT_TYPE_IMAGE; | 
| 104   } | 106   } | 
| 105   if (mimeType.Find(L"text/css") >= 0) | 107   if (mimeType.Find(L"text/css") >= 0) | 
| 106   { | 108   { | 
| 107     return CFilter::contentTypeStyleSheet; | 109     return ContentType::CONTENT_TYPE_STYLESHEET; | 
| 108   } | 110   } | 
| 109   if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic
     ation/json") >= 0)) | 111   if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic
     ation/json") >= 0)) | 
| 110   { | 112   { | 
| 111     return CFilter::contentTypeScript; | 113     return ContentType::CONTENT_TYPE_SCRIPT; | 
| 112   } | 114   } | 
| 113   if (mimeType.Find(L"application/x-shockwave-flash") >= 0) | 115   if (mimeType.Find(L"application/x-shockwave-flash") >= 0) | 
| 114   { | 116   { | 
| 115     return CFilter::contentTypeObject; | 117     return ContentType::CONTENT_TYPE_OBJECT; | 
| 116   } | 118   } | 
| 117   if (mimeType.Find(L"text/html") >= 0) | 119   if (mimeType.Find(L"text/html") >= 0) | 
| 118   { | 120   { | 
| 119     return CFilter::contentTypeSubdocument; | 121     return ContentType::CONTENT_TYPE_SUBDOCUMENT; | 
| 120   } | 122   } | 
| 121   // It is important to have this check last, since it is rather generic, and mi
     ght overlay text/html, for example | 123   // It is important to have this check last, since it is rather generic, and mi
     ght overlay text/html, for example | 
| 122   if (mimeType.Find(L"xml") >= 0) | 124   if (mimeType.Find(L"xml") >= 0) | 
| 123   { | 125   { | 
| 124     return CFilter::contentTypeXmlHttpRequest; | 126     return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; | 
| 125   } | 127   } | 
| 126 | 128 | 
| 127   return CFilter::contentTypeAny; | 129   return ContentType::CONTENT_TYPE_OTHER; | 
| 128 } | 130 } | 
| 129 | 131 | 
| 130 int WBPassthruSink::GetContentTypeFromURL(const std::wstring& src) | 132 ContentType WBPassthruSink::GetContentTypeFromURL(const std::wstring& src) | 
| 131 { | 133 { | 
| 132   CString srcLegacy = ToCString(src); | 134   CString srcLegacy = ToCString(src); | 
| 133   CString srcExt = srcLegacy; | 135   CString srcExt = srcLegacy; | 
| 134 | 136 | 
| 135   int pos = 0; | 137   int pos = 0; | 
| 136   if ((pos = srcLegacy.Find('?')) > 0) | 138   if ((pos = srcLegacy.Find('?')) > 0) | 
| 137   { | 139   { | 
| 138     srcExt = srcLegacy.Left(pos); | 140     srcExt = srcLegacy.Left(pos); | 
| 139   } | 141   } | 
| 140 | 142 | 
| 141   int lastDotIndex = srcExt.ReverseFind('.'); | 143   int lastDotIndex = srcExt.ReverseFind('.'); | 
| 142   if (lastDotIndex < 0) | 144   if (lastDotIndex < 0) | 
| 143     return CFilter::contentTypeAny; | 145     return ContentType::CONTENT_TYPE_OTHER; | 
| 144   CString ext = srcExt.Mid(lastDotIndex); | 146   CString ext = srcExt.Mid(lastDotIndex); | 
| 145   if (ext == L".jpg" || ext == L".gif" || ext == L".png" || ext == L".jpeg") | 147   if (ext == L".jpg" || ext == L".gif" || ext == L".png" || ext == L".jpeg") | 
| 146   { | 148   { | 
| 147     return CFilter::contentTypeImage; | 149     return ContentType::CONTENT_TYPE_IMAGE; | 
| 148   } | 150   } | 
| 149   else if (ext == L".css") | 151   else if (ext == L".css") | 
| 150   { | 152   { | 
| 151     return CFilter::contentTypeStyleSheet; | 153     return ContentType::CONTENT_TYPE_STYLESHEET; | 
| 152   } | 154   } | 
| 153   else if (ext.Right(3) == L".js") | 155   else if (ext.Right(3) == L".js") | 
| 154   { | 156   { | 
| 155     return CFilter::contentTypeScript; | 157     return ContentType::CONTENT_TYPE_SCRIPT; | 
| 156   } | 158   } | 
| 157   else if (ext == L".xml") | 159   else if (ext == L".xml") | 
| 158   { | 160   { | 
| 159     return CFilter::contentTypeXmlHttpRequest; | 161     return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; | 
| 160   } | 162   } | 
| 161   else if (ext == L".swf") | 163   else if (ext == L".swf") | 
| 162   { | 164   { | 
| 163     return CFilter::contentTypeObject; | 165     return ContentType::CONTENT_TYPE_OBJECT; | 
| 164   } | 166   } | 
| 165   else if (ext == L".jsp" || ext == L".php" || ext == L".html") | 167   else if (ext == L".jsp" || ext == L".php" || ext == L".html") | 
| 166   { | 168   { | 
| 167     return CFilter::contentTypeSubdocument; | 169     return ContentType::CONTENT_TYPE_SUBDOCUMENT; | 
| 168   } | 170   } | 
| 169   return CFilter::contentTypeAny; | 171   return ContentType::CONTENT_TYPE_OTHER; | 
| 170 } | 172 } | 
| 171 | 173 | 
| 172 int WBPassthruSink::GetContentType(const CString& mimeType, const std::wstring& 
     domain, const std::wstring& src) | 174 ContentType WBPassthruSink::GetContentType(const CString& mimeType, const std::w
     string& domain, const std::wstring& src) | 
| 173 { | 175 { | 
| 174   // No referer or mime type | 176   // No referer or mime type | 
| 175   // BINDSTRING_XDR_ORIGIN works only for IE v8+ | 177   // BINDSTRING_XDR_ORIGIN works only for IE v8+ | 
| 176   if (mimeType.IsEmpty() && domain.empty() && AdblockPlus::IE::InstalledMajorVer
     sion() >= 8) | 178   if (mimeType.IsEmpty() && domain.empty() && AdblockPlus::IE::InstalledMajorVer
     sion() >= 8) | 
| 177   { | 179   { | 
| 178     return CFilter::contentTypeXmlHttpRequest; | 180     return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; | 
| 179   } | 181   } | 
| 180   int contentType = GetContentTypeFromMimeType(mimeType); | 182   ContentType contentType = GetContentTypeFromMimeType(mimeType); | 
| 181   if (contentType == CFilter::contentTypeAny) | 183   if (contentType == ContentType::CONTENT_TYPE_OTHER) | 
| 182   { | 184   { | 
| 183     contentType = GetContentTypeFromURL(src); | 185     contentType = GetContentTypeFromURL(src); | 
| 184   } | 186   } | 
| 185   return contentType; | 187   return contentType; | 
| 186 } | 188 } | 
| 187 | 189 | 
| 188 ////////////////////////////////////////////////////////////////////////////////
     //////// | 190 ////////////////////////////////////////////////////////////////////////////////
     //////// | 
| 189 //WBPassthruSink | 191 //WBPassthruSink | 
| 190 //Monitor and/or cancel every request and responde | 192 //Monitor and/or cancel every request and responde | 
| 191 //WB makes, including images, sounds, scripts, etc | 193 //WB makes, including images, sounds, scripts, etc | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 312   // This fills the pszAdditionalHeaders with more headers. One of which is the 
     Referer header, which we need. | 314   // This fills the pszAdditionalHeaders with more headers. One of which is the 
     Referer header, which we need. | 
| 313   // There doesn't seem to be any other way to get this header before the reques
     t has been made. | 315   // There doesn't seem to be any other way to get this header before the reques
     t has been made. | 
| 314   HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, 
     szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; | 316   HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, 
     szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; | 
| 315 | 317 | 
| 316   if (pszAdditionalHeaders && *pszAdditionalHeaders) | 318   if (pszAdditionalHeaders && *pszAdditionalHeaders) | 
| 317   { | 319   { | 
| 318     m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref
     erer:", L"\n"); | 320     m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref
     erer:", L"\n"); | 
| 319   } | 321   } | 
| 320   m_boundDomain = TrimString(m_boundDomain); | 322   m_boundDomain = TrimString(m_boundDomain); | 
| 321   m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDoma
     in, src); | 323   m_contentType = GetContentType(ATL::CString(acceptHeader.c_str()), m_boundDoma
     in, src); | 
|  | 324 | 
| 322   CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); | 325   CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); | 
| 323   CPluginClient* client = CPluginClient::GetInstance(); | 326   CPluginClient* client = CPluginClient::GetInstance(); | 
| 324 | 327 | 
| 325   if (tab && client) | 328   if (tab && client) | 
| 326   { | 329   { | 
| 327     std::wstring documentUrl = tab->GetDocumentUrl(); | 330     std::wstring documentUrl = tab->GetDocumentUrl(); | 
| 328     // Page is identical to document => don't block | 331     // Page is identical to document => don't block | 
| 329     if (documentUrl == src) | 332     if (documentUrl == src) | 
| 330     { | 333     { | 
| 331       return nativeHr; | 334       return nativeHr; | 
| 332     } | 335     } | 
| 333     else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi
     telistedUrl(documentUrl)) | 336     else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi
     telistedUrl(std::wstring(documentUrl))) | 
| 334     { | 337     { | 
| 335       if (tab->IsFrameCached(src)) | 338       if (tab->IsFrameCached(src)) | 
| 336       { | 339       { | 
| 337         m_contentType = CFilter::contentTypeSubdocument; | 340         m_contentType = ContentType::CONTENT_TYPE_SUBDOCUMENT; | 
| 338       } | 341       } | 
| 339     } | 342     } | 
| 340   } | 343   } | 
| 341 | 344 | 
| 342   if (IsFlashRequest(pszAdditionalHeaders)) | 345   if (IsFlashRequest(pszAdditionalHeaders)) | 
| 343   { | 346   { | 
| 344     m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; | 347     m_contentType = ContentType::CONTENT_TYPE_OBJECT_SUBREQUEST; | 
| 345   } | 348   } | 
| 346 | 349 | 
| 347   if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi
     tionalHeaders)) | 350   if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi
     tionalHeaders)) | 
| 348   { | 351   { | 
| 349     m_contentType = CFilter::EContentType::contentTypeXmlHttpRequest; | 352     m_contentType = ContentType::CONTENT_TYPE_XMLHTTPREQUEST; | 
| 350   } | 353   } | 
| 351 | 354 | 
| 352   if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but 
     must be set*/true)) | 355   if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but 
     must be set*/true)) | 
| 353   { | 356   { | 
| 354     // NOTE: Feeding custom HTML to Flash, instead of original object subrequest | 357     // NOTE: Feeding custom HTML to Flash, instead of original object subrequest | 
| 355     // doesn't have much sense. It also can manifest in unwanted result» | 358     // doesn't have much sense. It also can manifest in unwanted result | 
| 356     // like video being blocked (See https://issues.adblockplus.org/ticket/1669)
     » | 359     // like video being blocked (See https://issues.adblockplus.org/ticket/1669) | 
| 357     // So we report blocked object subrequests as failed, not just empty HTML. | 360     // So we report blocked object subrequests as failed, not just empty HTML. | 
| 358     m_isCustomResponse = m_contentType != CFilter::contentTypeObjectSubrequest; | 361     m_isCustomResponse = m_contentType != ContentType::CONTENT_TYPE_OBJECT_SUBRE
     QUEST; | 
| 359     return E_ABORT; | 362     return E_ABORT; | 
| 360   } | 363   } | 
| 361   return nativeHr; | 364   return nativeHr; | 
| 362 } | 365 } | 
| 363 | 366 | 
| 364 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse
     Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) | 367 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse
     Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) | 
| 365 { | 368 { | 
| 366   if (pszAdditionalRequestHeaders) | 369   if (pszAdditionalRequestHeaders) | 
| 367   { | 370   { | 
| 368     *pszAdditionalRequestHeaders = 0; | 371     *pszAdditionalRequestHeaders = 0; | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 407   } | 410   } | 
| 408 | 411 | 
| 409   return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne
     tProtocol); | 412   return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne
     tProtocol); | 
| 410 } | 413 } | 
| 411 | 414 | 
| 412 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o
     ut] */ ULONG *pcbRead) | 415 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o
     ut] */ ULONG *pcbRead) | 
| 413 { | 416 { | 
| 414   WBPassthruSink* pSink = GetSink(); | 417   WBPassthruSink* pSink = GetSink(); | 
| 415   return pSink->OnRead(pv, cb, pcbRead); | 418   return pSink->OnRead(pv, cb, pcbRead); | 
| 416 } | 419 } | 
| OLD | NEW | 
|---|