| Index: src/plugin/PluginWbPassThrough.cpp |
| =================================================================== |
| --- a/src/plugin/PluginWbPassThrough.cpp |
| +++ b/src/plugin/PluginWbPassThrough.cpp |
| @@ -9,7 +9,7 @@ |
| #include "PluginSettings.h" |
| #include "PluginClass.h" |
| #include "PluginSystem.h" |
| - |
| +#include <WinInet.h> |
| #include "wtypes.h" |
| namespace |
| @@ -22,6 +22,12 @@ |
| "</html>"; |
| } |
| +WBPassthruSink::WBPassthruSink() |
| + : m_currentPositionOfSentPage(0) |
| + , m_contentType(CFilter::EContentType::contentTypeAny) |
| +{ |
| +} |
| + |
| int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) |
| { |
| if (mimeType.Find(L"image/") >= 0) |
| @@ -44,12 +50,6 @@ |
| { |
| return CFilter::contentTypeSubdocument; |
| } |
| - // It is important to have this check last, since it is rather generic, and might overlay text/html, for example |
| - if (mimeType.Find(L"xml") >= 0) |
| - { |
| - return CFilter::contentTypeXmlHttpRequest; |
| - } |
| - |
| return CFilter::contentTypeAny; |
| } |
| @@ -79,10 +79,6 @@ |
| { |
| return CFilter::contentTypeScript; |
| } |
| - else if (ext == L".xml") |
| - { |
| - return CFilter::contentTypeXmlHttpRequest; |
| - } |
| else if (ext == L".swf") |
| { |
| return CFilter::contentTypeObject; |
| @@ -91,8 +87,7 @@ |
| { |
| return CFilter::contentTypeSubdocument; |
| } |
| - |
| - return CFilter::contentTypeAny & ~CFilter::contentTypeSubdocument; |
| + return CFilter::contentTypeAny; |
| } |
| int WBPassthruSink::GetContentType(const CString& mimeType, const CString& domain, const CString& src) |
| @@ -122,35 +117,32 @@ |
| { |
| m_pTargetProtocol = pTargetProtocol; |
| bool isBlocked = false; |
| - m_currentPositionOfSentPage = 0; |
| CString src = szUrl; |
| DEBUG_GENERAL(src); |
| CPluginClient::UnescapeUrl(src); |
| - CString boundDomain; |
| CString mimeType; |
| - LPOLESTR mime[10]; |
| if (pOIBindInfo) |
| { |
| ULONG resLen = 0; |
| // Apparently IE will report random mime type if there's more then 1 in the list. |
| // So we get the whole list and just use the first one (top priority one) |
| + LPOLESTR mime[10]; |
| pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, mime, 10, &resLen); |
| if (mime && resLen > 0) |
| { |
| mimeType.SetString(mime[0]); |
| } |
| - LPOLESTR bindToObject = 0; |
| + LPOLESTR bindToObject = nullptr; |
| pOIBindInfo->GetBindString(BINDSTRING_FLAG_BIND_TO_OBJECT, &bindToObject, 1, &resLen); |
| - LPOLESTR domainRetrieved = 0; |
| + LPOLESTR domainRetrieved = nullptr; |
| if (resLen == 0 || wcscmp(bindToObject, L"FALSE") == 0) |
| - { |
| + { |
| HRESULT hr = pOIBindInfo->GetBindString(BINDSTRING_XDR_ORIGIN, &domainRetrieved, 1, &resLen); |
| - |
| if ((hr == S_OK) && domainRetrieved && (resLen > 0)) |
| { |
| - boundDomain.SetString(domainRetrieved); |
| + m_boundDomain = domainRetrieved; |
| } |
| } |
| } |
| @@ -160,12 +152,9 @@ |
| ULONG len2 = 2048; |
| #ifdef SUPPORT_FILTER |
| - int contentType = CFilter::contentTypeAny; |
| - |
| CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); |
| CPluginClient* client = CPluginClient::GetInstance(); |
| - |
| if (tab && client) |
| { |
| CString documentUrl = tab->GetDocumentUrl(); |
| @@ -176,104 +165,68 @@ |
| } |
| else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhitelistedUrl(std::wstring(documentUrl))) |
| { |
| - boundDomain = tab->GetDocumentUrl(); |
| - |
| - contentType = CFilter::contentTypeAny; |
| - |
| + m_boundDomain = tab->GetDocumentUrl(); |
| + m_contentType = CFilter::contentTypeAny; |
| #ifdef SUPPORT_FRAME_CACHING |
| - if ((tab != 0) && (tab->IsFrameCached(src))) |
| + if (nullptr != tab && tab->IsFrameCached(src)) |
| { |
| - contentType = CFilter::contentTypeSubdocument; |
| + m_contentType = CFilter::contentTypeSubdocument; |
| } |
| else |
| #endif // SUPPORT_FRAME_CACHING |
| - contentType = GetContentType(mimeType, boundDomain, src); |
| - if (client->ShouldBlock(src, contentType, boundDomain, true)) |
| { |
| - isBlocked = true; |
| - |
| - DEBUG_BLOCKER("Blocker::Blocking Http-request:" + src); |
| + m_contentType = GetContentType(mimeType, m_boundDomain, src); |
| } |
| } |
| - if (!isBlocked) |
| - { |
| - DEBUG_BLOCKER("Blocker::Ignoring Http-request:" + src) |
| - } |
| + |
| } |
| - |
| - if (tab == NULL) |
| + if (nullptr == tab) |
| { |
| - contentType = GetContentType(mimeType, boundDomain, src); |
| - if (client->ShouldBlock(src, contentType, boundDomain, true)) |
| - { |
| - isBlocked = true; |
| - } |
| + m_contentType = GetContentType(mimeType, m_boundDomain, src); |
| } |
| -#ifdef _DEBUG |
| - CString type; |
| + if (nullptr != client |
| + && CFilter::EContentType::contentTypeAny != m_contentType |
|
Oleksandr
2014/09/11 08:58:54
This line is not clear to me. We can in theory blo
sergei
2014/09/11 09:53:25
If the type is `contentTypeAny` then the decision
|
| + && client->ShouldBlock(src, m_contentType, m_boundDomain, true)) |
| + { |
| + isBlocked = true; |
| + DEBUG_BLOCKER("Blocker::Blocking Http-request:" + src); |
|
Oleksandr
2014/09/11 08:58:54
DEBUG_BLOCKER is broken here. Either use CPluginDe
sergei
2014/09/11 09:53:25
`client->ShouldBlock` already puts into the log. `
|
| + } |
| + if (!isBlocked) |
| + { |
| + DEBUG_BLOCKER("Blocker::Ignoring Http-request:" + src) |
|
Oleksandr
2014/09/11 08:58:54
CPluginDebug::DebugResultIgnoring here accordingly
sergei
2014/09/11 09:53:25
The same as above, deleted.
|
| + } |
| - if (contentType == CFilter::contentTypeDocument) type = "DOCUMENT"; |
| - else if (contentType == CFilter::contentTypeObject) type = "OBJECT"; |
| - else if (contentType == CFilter::contentTypeImage) type = "IMAGE"; |
| - else if (contentType == CFilter::contentTypeScript) type = "SCRIPT"; |
| - else if (contentType == CFilter::contentTypeOther) type = "OTHER"; |
| - else if (contentType == CFilter::contentTypeUnknown) type = "OTHER"; |
| - else if (contentType == CFilter::contentTypeSubdocument) type = "SUBDOCUMENT"; |
| - else if (contentType == CFilter::contentTypeStyleSheet) type = "STYLESHEET"; |
| - else type = "OTHER"; |
|
Oleksandr
2014/09/11 08:58:54
We will still need a way to convert contentType to
sergei
2014/09/11 09:53:25
It's done in `CPluginFilter`
|
| - |
| - if (isBlocked) |
| + // For IE6 and earlier there is iframe back button issue, so avoid it. |
| + if (isBlocked && client->GetIEVersion() > 6) |
| { |
| - CPluginDebug::DebugResultBlocking(type, src, boundDomain); |
| - } |
| - else |
| - { |
| - CPluginDebug::DebugResultIgnoring(type, src, boundDomain); |
| - } |
| -#endif |
| - |
| - //Fixes the iframe back button issue |
| - if (client->GetIEVersion() > 6) |
| - { |
| - if (contentType == CFilter::contentTypeImage && isBlocked) |
| + handled = true; |
| + if (CFilter::EContentType::contentTypeImage == m_contentType) |
| { |
| BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| - handled = true; |
| // IE shows a cross that img is not loaded |
| return INET_E_REDIRECT_FAILED; |
| } |
| - if (contentType == CFilter::contentTypeSubdocument && isBlocked) |
| + if (CFilter::EContentType::contentTypeSubdocument == m_contentType) |
| { |
| PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProtocol(this)->m_shouldSupplyCustomContent = true; |
| BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| - |
| m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"text/html"); |
| m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, static_cast<ULONG>(g_myPageBlocked.size())); |
| - handled = true; |
| return S_OK; |
| } |
| - if (contentType == CFilter::contentTypeScript && isBlocked) |
| + if (CFilter::EContentType::contentTypeScript == m_contentType) |
| { |
| BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"text/javascript"); |
| m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); |
| - handled = true; |
| return INET_E_REDIRECT_FAILED; |
| } |
| - if (contentType == CFilter::contentTypeXmlHttpRequest && isBlocked) |
| + if (CFilter::EContentType::contentTypeXmlHttpRequest == m_contentType) |
| { |
| BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:"); |
| - handled = true; |
| - return INET_E_REDIRECT_FAILED; |
| - } |
| - if (isBlocked) |
| - { |
| - BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| - m_spInternetProtocolSink->ReportResult(S_FALSE, 0, L""); |
| - handled = true; |
| return INET_E_REDIRECT_FAILED; |
| } |
| } |
| @@ -282,7 +235,6 @@ |
| return isBlocked ? S_FALSE : BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| } |
| - |
| HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) |
| { |
| if (nullptr == pv) |
| @@ -348,13 +300,62 @@ |
| return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolData) : E_UNEXPECTED; |
| } |
| -STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) |
| +STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) |
| { |
| if (pszAdditionalHeaders) |
| { |
| - *pszAdditionalHeaders = 0; |
| + *pszAdditionalHeaders = nullptr; |
| } |
| + CPluginClient* client = nullptr; |
| + if (CFilter::EContentType::contentTypeAny == m_contentType && (client = CPluginClient::GetInstance())) |
| + { |
| + auto acceptHeader = [&]() -> std::string |
|
Oleksandr
2014/09/11 08:58:54
I'd just like to say this looks too cool :D
sergei
2014/09/11 09:53:25
Thanks!
|
| + { |
| + ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo; |
| + HRESULT hr = m_spTargetProtocol->QueryInterface(&winInetHttpInfo); |
| + if(FAILED(hr)) |
| + { |
| + return ""; |
| + } |
| + DWORD size = 0; |
| + DWORD flags = 0; |
| + hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS, |
| + /*buffer*/nullptr, /* get size */&size, &flags, /*reserved*/ 0); |
| + if(FAILED(hr)) |
| + { |
| + return ""; |
| + } |
| + std::string buf(size, '\0'); |
| + hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS, |
| + &buf[0], &size, &flags, 0); |
| + if(FAILED(hr)) |
| + { |
| + return ""; |
| + } |
| + char acceptHeader[] = "Accept:"; |
| + auto acceptHeaderBeginsAt = buf.find(acceptHeader); |
| + if (std::string::npos == acceptHeaderBeginsAt) |
| + { |
| + return ""; |
| + } |
| + acceptHeaderBeginsAt += sizeof(acceptHeader); |
| + auto acceptHeaderEndsAt = buf.find("\n", acceptHeaderBeginsAt); |
| + if (std::string::npos == acceptHeaderEndsAt) |
| + { |
| + return ""; |
| + } |
| + return buf.substr(acceptHeaderBeginsAt, acceptHeaderEndsAt - acceptHeaderBeginsAt); |
| + }(); |
| + m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str())); |
| + bool isBlocked = client->ShouldBlock(szURL, m_contentType, |
| + //client->GetHostFromUrl(m_boundDomain.operator LPCWSTR()).c_str(), /*debug flag but must be set*/true); |
|
Oleksandr
2014/09/11 08:58:54
Leftover code here?
sergei
2014/09/11 09:53:25
Thanks, removed.
|
| + m_boundDomain, /*debug flag but must be set*/true); |
| + if (isBlocked) |
| + { |
|
Oleksandr
2014/09/11 08:58:54
Log blocking here as well
sergei
2014/09/11 09:53:25
`client->ShouldBlock` puts into log
|
| + return E_ABORT; |
| + } |
| + } |
| CComPtr<IHttpNegotiate> spHttpNegotiate; |
| QueryServiceFromClient(&spHttpNegotiate); |
| return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeaders,dwReserved, pszAdditionalHeaders) : S_OK; |