| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 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 #ifdef SUPPORT_FILTER | |
| 7 #include "PluginFilter.h" | 6 #include "PluginFilter.h" |
| 8 #endif | |
| 9 #include "PluginSettings.h" | 7 #include "PluginSettings.h" |
| 10 #include "PluginClass.h" | 8 #include "PluginClass.h" |
| 11 #include "PluginSystem.h" | 9 #include "PluginSystem.h" |
| 12 #include <WinInet.h> | 10 #include <WinInet.h> |
| 13 #include "wtypes.h" | 11 #include "wtypes.h" |
| 12 #include "../shared/Utils.h" | |
| 14 | 13 |
| 15 namespace | 14 namespace |
| 16 { | 15 { |
| 17 std::string g_blockedByABPPage = "<!DOCTYPE html>" | 16 std::string g_blockedByABPPage = "<!DOCTYPE html>" |
| 18 "<html>" | 17 "<html>" |
| 19 "<body>" | 18 "<body>" |
| 20 "<!-- blocked by AdblockPlus -->" | 19 "<!-- blocked by AdblockPlus -->" |
| 21 "</body>" | 20 "</body>" |
| 22 "</html>"; | 21 "</html>"; |
| 22 | |
| 23 template <class T> | |
| 24 T ExtractHttpHeader(const T& allHeaders, const T& targetHeaderNameWithColon, c onst T& delimiter) | |
| 25 { | |
| 26 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderNameWithColon); | |
| 27 if (targetHeaderBeginsAt == T::npos) | |
| 28 { | |
| 29 return T(); | |
| 30 } | |
| 31 targetHeaderBeginsAt += targetHeaderNameWithColon.length(); | |
| 32 auto targetHeaderEndsAt = allHeaders.find(delimiter, targetHeaderBeginsAt); | |
| 33 if (targetHeaderEndsAt == T::npos) | |
| 34 { | |
| 35 return T(); | |
| 36 } | |
| 37 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHe aderBeginsAt); | |
| 38 } | |
| 39 | |
| 40 std::string ExtractHttpAcceptHeader(IInternetProtocol* internetProtocol) | |
| 41 { | |
| 42 // 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 ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo; | |
| 45 HRESULT hr = internetProtocol->QueryInterface(&winInetHttpInfo); | |
| 46 if (FAILED(hr)) | |
| 47 { | |
| 48 return ""; | |
| 49 } | |
| 50 DWORD size = 0; | |
| 51 DWORD flags = 0; | |
| 52 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 if (FAILED(hr)) | |
| 55 { | |
| 56 return ""; | |
| 57 } | |
| 58 std::string buf(size, '\0'); | |
| 59 hr = winInetHttpInfo->QueryInfo(queryOption, &buf[0], &size, &flags, 0); | |
| 60 if (FAILED(hr)) | |
| 61 { | |
| 62 return ""; | |
| 63 } | |
| 64 return ExtractHttpHeader<std::string>(buf, "Accept:", "\r\n"); | |
| 65 } | |
| 23 } | 66 } |
| 24 | 67 |
| 25 WBPassthruSink::WBPassthruSink() | 68 WBPassthruSink::WBPassthruSink() |
| 26 : m_currentPositionOfSentPage(0) | 69 : m_currentPositionOfSentPage(0) |
| 27 , m_contentType(CFilter::EContentType::contentTypeAny) | 70 , m_contentType(CFilter::EContentType::contentTypeAny) |
| 28 , m_blockedInTransaction(false) | 71 , m_blockedInTransaction(false) |
| 29 { | 72 { |
| 30 } | 73 } |
| 31 | 74 |
| 32 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) | 75 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 { | 137 { |
| 95 return CFilter::contentTypeObject; | 138 return CFilter::contentTypeObject; |
| 96 } | 139 } |
| 97 else if (ext == L".jsp" || ext == L".php" || ext == L".html") | 140 else if (ext == L".jsp" || ext == L".php" || ext == L".html") |
| 98 { | 141 { |
| 99 return CFilter::contentTypeSubdocument; | 142 return CFilter::contentTypeSubdocument; |
| 100 } | 143 } |
| 101 return CFilter::contentTypeAny; | 144 return CFilter::contentTypeAny; |
| 102 } | 145 } |
| 103 | 146 |
| 104 int WBPassthruSink::GetContentType(const CString& mimeType, const CString& domai n, const CString& src) | 147 int WBPassthruSink::GetContentType(const CString& mimeType, const std::wstring& domain, const CString& src) |
| 105 { | 148 { |
| 106 // No referer or mime type | 149 // No referer or mime type |
| 107 // BINDSTRING_XDR_ORIGIN works only for IE v8+ | 150 // BINDSTRING_XDR_ORIGIN works only for IE v8+ |
| 108 if (mimeType.IsEmpty() && domain.IsEmpty() && CPluginClient::GetInstance()->Ge tIEVersion() >= 8) | 151 if (mimeType.IsEmpty() && domain.empty() && CPluginClient::GetInstance()->GetI EVersion() >= 8) |
| 109 { | 152 { |
| 110 return CFilter::contentTypeXmlHttpRequest; | 153 return CFilter::contentTypeXmlHttpRequest; |
| 111 } | 154 } |
| 112 int contentType = GetContentTypeFromMimeType(mimeType); | 155 int contentType = GetContentTypeFromMimeType(mimeType); |
| 113 if (contentType == CFilter::contentTypeAny) | 156 if (contentType == CFilter::contentTypeAny) |
| 114 { | 157 { |
| 115 contentType = GetContentTypeFromURL(src); | 158 contentType = GetContentTypeFromURL(src); |
| 116 } | 159 } |
| 117 return contentType; | 160 return contentType; |
| 118 } | 161 } |
| 119 | 162 |
| 120 //////////////////////////////////////////////////////////////////////////////// //////// | 163 //////////////////////////////////////////////////////////////////////////////// //////// |
| 121 //WBPassthruSink | 164 //WBPassthruSink |
| 122 //Monitor and/or cancel every request and responde | 165 //Monitor and/or cancel every request and responde |
| 123 //WB makes, including images, sounds, scripts, etc | 166 //WB makes, including images, sounds, scripts, etc |
| 124 //////////////////////////////////////////////////////////////////////////////// //////// | 167 //////////////////////////////////////////////////////////////////////////////// //////// |
| 125 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, | 168 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, |
| 126 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, | 169 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, |
| 127 IInternetProtocol* pTargetProtocol, bool& handle d) | 170 IInternetProtocol* pTargetProtocol, bool& handle d) |
| 128 { | 171 { |
| 129 m_pTargetProtocol = pTargetProtocol; | 172 m_pTargetProtocol = pTargetProtocol; |
| 130 // call the impl of the base class as soon as possible because it initializes the base class | 173 return BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol); |
| 131 // members, used by this method. It queries for the required interfaces. | |
| 132 HRESULT hr = BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwRese rved, pTargetProtocol); | |
| 133 if (FAILED(hr)) | |
| 134 { | |
| 135 return hr; | |
| 136 } | |
| 137 return hr; | |
| 138 } | 174 } |
| 139 | 175 |
| 140 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) | 176 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead) |
| 141 { | 177 { |
| 142 if (nullptr == pv) | 178 if (pv == nullptr) |
| 143 { | 179 { |
| 144 return E_POINTER; | 180 return E_POINTER; |
| 145 } | 181 } |
| 146 if (nullptr == pcbRead) | 182 if (pcbRead == nullptr) |
| 147 { | 183 { |
| 148 return E_POINTER; | 184 return E_POINTER; |
| 149 } | 185 } |
| 150 *pcbRead = 0; | 186 *pcbRead = 0; |
| 151 | 187 |
| 152 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent) | 188 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent) |
| 153 { | 189 { |
| 154 ULONG myPageSize = static_cast<ULONG>(g_blockedByABPPage.size()); | 190 ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size()); |
| 155 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(g_blockedByABPPag e.size() - m_currentPositionOfSentPage)); | 191 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS ize - m_currentPositionOfSentPage)); |
| 156 if (0 == positionGrow) { | 192 if (positionGrow == 0) { |
| 157 return S_FALSE; | 193 return S_FALSE; |
| 158 } | 194 } |
| 159 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row, | 195 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row, |
| 160 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); | 196 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb)); |
| 161 *pcbRead = positionGrow; | 197 *pcbRead = positionGrow; |
| 162 m_currentPositionOfSentPage += positionGrow; | 198 m_currentPositionOfSentPage += positionGrow; |
| 163 | 199 |
| 164 if (m_spInternetProtocolSink) | 200 if (m_spInternetProtocolSink) |
| 165 { | 201 { |
| 166 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, | 202 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, |
| 167 static_cast<ULONG>(m_currentPositionOfSentPage), myPageSize); | 203 static_cast<ULONG>(m_currentPositionOfSentPage), blockedByABPPageSize); |
| 168 } | 204 } |
| 169 if (myPageSize == m_currentPositionOfSentPage && m_spInternetProtocolSink) | 205 if (blockedByABPPageSize == m_currentPositionOfSentPage && m_spInternetProto colSink) |
| 170 { | 206 { |
| 171 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, myPageSize, myPageSize); | 207 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, blockedByABP PageSize, blockedByABPPageSize); |
| 172 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); | 208 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr); |
| 173 } | 209 } |
| 174 return S_OK; | 210 return S_OK; |
| 175 } | 211 } |
| 176 return m_pTargetProtocol->Read(pv, cb, pcbRead); | 212 return m_pTargetProtocol->Read(pv, cb, pcbRead); |
| 177 } | 213 } |
| 178 STDMETHODIMP WBPassthruSink::Switch( | 214 STDMETHODIMP WBPassthruSink::Switch( |
| 179 /* [in] */ PROTOCOLDATA *pProtocolData) | 215 /* [in] */ PROTOCOLDATA *pProtocolData) |
| 180 { | 216 { |
| 181 ATLASSERT(m_spInternetProtocolSink != 0); | 217 ATLASSERT(m_spInternetProtocolSink != 0); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 194 IInternetProtocolSink::Switch with PD_FORCE_SWITCH flag in | 230 IInternetProtocolSink::Switch with PD_FORCE_SWITCH flag in |
| 195 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call | 231 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call |
| 196 IInternetProtocol::Continue on the main thread. | 232 IInternetProtocol::Continue on the main thread. |
| 197 | 233 |
| 198 Or, if you happen to have a window handy that was created on the main | 234 Or, if you happen to have a window handy that was created on the main |
| 199 thread, you can post yourself a message. | 235 thread, you can post yourself a message. |
| 200 " | 236 " |
| 201 */ | 237 */ |
| 202 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED; | 238 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED; |
| 203 } | 239 } |
| 204 std::wstring ExtractHTTPHeader(const std::wstring& allHeaders, const std::wstrin g& targetHeaderName) | 240 |
| 205 { | 241 // This is the heuristic which detects the requests issued by Flash.ocx. |
| 206 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderName); | 242 // It turned out that the implementation from ''Flash.ocx'' (tested version is 1 5.0.0.152) |
| 207 if (std::string::npos == targetHeaderBeginsAt ) | 243 // returns quite minimal configuration in comparison with the implementation fro m Microsofts' |
| 208 { | 244 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often inclu des something |
| 209 return L""; | 245 // else. |
| 210 } | 246 bool WBPassthruSink::IsFlashRequest() |
| 211 targetHeaderBeginsAt += targetHeaderName.length(); | 247 { |
| 212 auto targetHeaderEndsAt = allHeaders.find(L"\n", targetHeaderBeginsAt); | 248 ATL::CComPtr<IBindStatusCallback> bscb; |
| 213 if (std::string::npos == targetHeaderEndsAt) | 249 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb) |
| 214 { | 250 { |
| 215 return L""; | 251 DWORD grfBINDF = 0; |
| 216 } | 252 BINDINFO bindInfo = {}; |
| 217 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHead erBeginsAt); | 253 bindInfo.cbSize = sizeof(bindInfo); |
| 218 } | 254 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) && |
| 219 | 255 (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF && |
|
Eric
2014/10/15 17:02:33
If we really need both standard and wide versions
| |
| 220 std::string ExtractHTTPHeader(const std::string& allHeaders, const std::string& targetHeaderName) | 256 (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindI nfo.dwOptions |
| 221 { | 257 ) |
| 222 auto targetHeaderBeginsAt = allHeaders.find(targetHeaderName); | 258 { |
| 223 if (std::string::npos == targetHeaderBeginsAt ) | 259 return true; |
| 224 { | 260 } |
| 225 return ""; | 261 } |
| 226 } | 262 return false; |
| 227 targetHeaderBeginsAt += targetHeaderName.length(); | |
| 228 auto targetHeaderEndsAt = allHeaders.find("\r\n", targetHeaderBeginsAt); | |
| 229 if (std::string::npos == targetHeaderEndsAt) | |
| 230 { | |
| 231 return ""; | |
| 232 } | |
| 233 return allHeaders.substr(targetHeaderBeginsAt, targetHeaderEndsAt - targetHead erBeginsAt); | |
| 234 } | 263 } |
| 235 | 264 |
| 236 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) | 265 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders) |
| 237 { | 266 { |
| 267 std::wstring src = szURL; | |
| 268 DEBUG_GENERAL(ToCString(src)); | |
| 269 | |
| 270 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol); | |
| 271 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str())) ; | |
| 272 | |
| 238 if (pszAdditionalHeaders) | 273 if (pszAdditionalHeaders) |
| 239 { | 274 { |
| 240 *pszAdditionalHeaders = nullptr; | 275 *pszAdditionalHeaders = nullptr; |
| 241 } | 276 } |
| 242 | 277 |
| 243 CComPtr<IHttpNegotiate> spHttpNegotiate; | 278 CComPtr<IHttpNegotiate> httpNegotiate; |
| 244 QueryServiceFromClient(&spHttpNegotiate); | 279 QueryServiceFromClient(&httpNegotiate); |
| 245 HRESULT nativeHresult = spHttpNegotiate ? spHttpNegotiate->BeginningTransactio n(szURL, szHeaders,dwReserved, pszAdditionalHeaders) : S_OK; | 280 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need. |
|
Eric
2014/10/15 17:02:33
It would seem to me that if the service query fail
| |
| 246 | 281 // There doesn't seem to be any other way to get this header before the reques t has been made. |
| 247 bool isBlocked = false; | 282 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK; |
| 248 CString src = szURL; | 283 |
| 249 DEBUG_GENERAL(src); | 284 if (*pszAdditionalHeaders != 0) |
| 250 CPluginClient::UnescapeUrl(src); | 285 { |
| 251 | 286 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n").c_str(); |
| 252 CPluginClient* client = nullptr; | 287 } |
| 253 if (CFilter::EContentType::contentTypeAny == m_contentType && (client = CPlugi nClient::GetInstance())) | 288 m_boundDomain = TrimString(m_boundDomain); |
| 254 { | 289 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); |
| 255 auto acceptHeader = [&]() -> std::string | 290 CPluginClient* client = CPluginClient::GetInstance(); |
|
Eric
2014/10/15 17:02:33
This function does not look like a good candidate
Eric
2014/10/15 17:02:33
Also, it would be better generally to have 'accept
Oleksandr
2014/10/24 09:59:18
I think it's good to leave this as is, since it he
| |
| 256 { | 291 |
| 257 // Despite there is HTTP_QUERY_ACCEPT and other query info flags, they don 't work here, | 292 if (tab && client) |
| 258 // only HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS does dork. | 293 { |
|
Eric
2014/10/15 17:02:33
Doesn't HTTP_QUERY_CUSTOM work? If so, that would
Oleksandr
2014/10/24 09:59:18
No, it doesn't work. Added a comment about that.
| |
| 259 ATL::CComPtr<IWinInetHttpInfo> winInetHttpInfo; | 294 CString documentUrl = tab->GetDocumentUrl(); |
| 260 HRESULT hr = m_spTargetProtocol->QueryInterface(&winInetHttpInfo); | 295 // Page is identical to document => don't block |
| 261 if(FAILED(hr)) | 296 if (documentUrl == ToCString(src)) |
| 297 { | |
| 298 return nativeHr; | |
| 299 } | |
| 300 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(std::wstring(documentUrl))) | |
| 301 { | |
| 302 if (tab->IsFrameCached(ToCString(src))) | |
| 262 { | 303 { |
| 263 return ""; | 304 m_contentType = CFilter::contentTypeSubdocument; |
| 264 } | 305 } |
| 265 DWORD size = 0; | 306 } |
| 266 DWORD flags = 0; | 307 } |
| 267 hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_F LAG_REQUEST_HEADERS, | 308 |
| 268 /*buffer*/nullptr, /* get size */&size, &flags, /*reserved*/ 0); | 309 if (IsFlashRequest()) |
| 269 if(FAILED(hr)) | 310 { |
| 270 { | 311 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; |
| 271 return ""; | 312 } |
| 272 } | 313 |
| 273 std::string buf(size, '\0'); | 314 m_blockedInTransaction = client->ShouldBlock(szURL, m_contentType, m_boundDoma in, /*debug flag but must be set*/true); |
|
Eric
2014/10/15 17:02:33
I'll simply register my distaste for writing into
| |
| 274 hr = winInetHttpInfo->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_F LAG_REQUEST_HEADERS, | 315 if (m_blockedInTransaction) |
| 275 &buf[0], &size, &flags, 0); | 316 { |
| 276 if(FAILED(hr)) | 317 return E_ABORT; |
| 277 { | 318 } |
| 278 return ""; | 319 return nativeHr; |
| 279 } | |
| 280 return ExtractHTTPHeader(buf, "Accept:"); | |
| 281 }(); | |
| 282 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str() )); | |
| 283 | |
| 284 m_boundDomain = ExtractHTTPHeader(std::wstring(*pszAdditionalHeaders), L"Ref erer:").c_str(); | |
|
Eric
2014/10/15 17:02:33
In general, use 'ToCString()' here preferably. It
Eric
2014/10/15 17:02:33
Is it the case the "Referer" only ever appears in
sergei
2014/10/28 14:08:46
It indeed looks inconsistent although there is may
Oleksandr
2014/10/30 23:40:48
In my tests the Referer is available through Query
sergei
2014/10/31 12:47:57
It's OK for me.
| |
| 285 m_boundDomain = m_boundDomain.Trim(L" \r"); | |
| 286 CPluginClient::UnescapeUrl(m_boundDomain); | |
| 287 | |
| 288 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); | |
| 289 CPluginClient* client = CPluginClient::GetInstance(); | |
| 290 | |
| 291 if (tab && client) | |
| 292 { | |
| 293 CString documentUrl = tab->GetDocumentUrl(); | |
| 294 // Page is identical to document => don't block | |
| 295 if (documentUrl == src) | |
| 296 { | |
| 297 return nativeHresult; | |
| 298 } | |
| 299 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsW hitelistedUrl(std::wstring(documentUrl))) | |
| 300 { | |
|
Eric
2014/10/15 17:02:33
FYI. A solid reason to need a rewrite. The change
| |
| 301 #ifdef SUPPORT_FRAME_CACHING | |
| 302 if (tab->IsFrameCached(src)) | |
| 303 { | |
| 304 m_contentType = CFilter::contentTypeSubdocument; | |
| 305 } | |
| 306 #endif // SUPPORT_FRAME_CACHING | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 { | |
| 311 // Here is the heuristic which detects the requests issued by Flash.ocx. | |
| 312 // It turned out that the implementation from ''Flash.ocx'' (tested versio n is 15.0.0.152) | |
| 313 // returns quite minimal configuration in comparison with the implementati on from Microsofts' | |
| 314 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often includes something | |
| 315 // else. | |
| 316 ATL::CComPtr<IBindStatusCallback> bscb; | |
| 317 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb) | |
| 318 { | |
| 319 DWORD grfBINDF = 0; | |
| 320 BINDINFO bindInfo = {}; | |
| 321 bindInfo.cbSize = sizeof(bindInfo); | |
| 322 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) | |
| 323 && (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBIN DF | |
| 324 && (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) = = bindInfo.dwOptions | |
| 325 ) | |
| 326 { | |
| 327 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest; | |
| 328 } | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 if (nullptr != client | |
| 333 && client->ShouldBlock(src, m_contentType, m_boundDomain, true)) | |
| 334 { | |
| 335 isBlocked = true; | |
| 336 } | |
| 337 | |
| 338 // For IE6 and earlier there is iframe back button issue, so avoid it. | |
| 339 if (isBlocked && client->GetIEVersion() > 6) | |
| 340 { | |
| 341 if (CFilter::EContentType::contentTypeImage == m_contentType) | |
| 342 { | |
| 343 // IE shows a cross that img is not loaded | |
| 344 return INET_E_REDIRECT_FAILED; | |
| 345 } | |
| 346 if (CFilter::EContentType::contentTypeSubdocument == m_contentType) | |
| 347 { | |
| 348 PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetPr otocol(this)->m_shouldSupplyCustomContent = true; | |
| 349 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L "text/html"); | |
| 350 m_spInternetProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, stat ic_cast<ULONG>(g_blockedByABPPage.size())); | |
| 351 return S_OK; | |
| 352 } | |
| 353 if (CFilter::EContentType::contentTypeScript == m_contentType) | |
| 354 { | |
| 355 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L "text/javascript"); | |
| 356 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:" ); | |
| 357 return INET_E_REDIRECT_FAILED; | |
| 358 } | |
| 359 if (CFilter::EContentType::contentTypeXmlHttpRequest == m_contentType) | |
| 360 { | |
| 361 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:" ); | |
| 362 return INET_E_REDIRECT_FAILED; | |
| 363 } | |
| 364 if (CFilter::EContentType::contentTypeAny != m_contentType) | |
| 365 { | |
| 366 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:" ); | |
| 367 return INET_E_REDIRECT_FAILED; | |
| 368 } | |
| 369 } | |
| 370 if (isBlocked) | |
| 371 { | |
| 372 m_blockedInTransaction = true; | |
| 373 return E_ABORT; | |
| 374 } | |
| 375 } | |
| 376 | |
| 377 return nativeHresult; | |
| 378 } | 320 } |
| 379 | 321 |
| 380 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) | 322 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) |
| 381 { | 323 { |
| 382 if (pszAdditionalRequestHeaders) | 324 if (pszAdditionalRequestHeaders) |
| 383 { | 325 { |
| 384 *pszAdditionalRequestHeaders = 0; | 326 *pszAdditionalRequestHeaders = 0; |
| 385 } | 327 } |
| 386 | 328 |
| 387 CComPtr<IHttpNegotiate> spHttpNegotiate; | 329 CComPtr<IHttpNegotiate> spHttpNegotiate; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 403 // Current method is called by the original protocol implementation and we a re intercepting the | 345 // Current method is called by the original protocol implementation and we a re intercepting the |
| 404 // call here and eating it, we will call the proper ReportResult later by ou rself. | 346 // call here and eating it, we will call the proper ReportResult later by ou rself. |
| 405 return S_OK; | 347 return S_OK; |
| 406 } | 348 } |
| 407 return BaseClass::ReportResult(hrResult, dwError, szResult); | 349 return BaseClass::ReportResult(hrResult, dwError, szResult); |
| 408 } | 350 } |
| 409 | 351 |
| 410 | 352 |
| 411 WBPassthru::WBPassthru() | 353 WBPassthru::WBPassthru() |
| 412 : m_shouldSupplyCustomContent(false) | 354 : m_shouldSupplyCustomContent(false) |
| 413 , m_hasOriginalStartCalled(false) | |
| 414 { | 355 { |
| 415 } | 356 } |
| 416 | 357 |
| 417 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink , | 358 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink , |
| 418 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) | 359 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) |
| 419 { | 360 { |
| 420 ATLASSERT(m_spInternetProtocol != 0); | 361 ATLASSERT(m_spInternetProtocol != 0); |
| 421 if (!m_spInternetProtocol) | 362 if (!m_spInternetProtocol) |
| 422 { | 363 { |
| 423 return E_UNEXPECTED; | 364 return E_UNEXPECTED; |
| 424 } | 365 } |
| 425 | 366 |
| 426 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol); | 367 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol); |
| 427 } | 368 } |
| 428 | 369 |
| 429 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead) | 370 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead) |
| 430 { | 371 { |
| 431 WBPassthruSink* pSink = GetSink(); | 372 WBPassthruSink* pSink = GetSink(); |
| 432 return pSink->OnRead(pv, cb, pcbRead); | 373 return pSink->OnRead(pv, cb, pcbRead); |
| 433 } | 374 } |
| 434 | 375 |
| 435 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) | 376 STDMETHODIMP WBPassthru::LockRequest(/* [in] */ DWORD options) |
| 436 { | 377 { |
| 437 if (!m_hasOriginalStartCalled) | |
| 438 { | |
| 439 return S_OK; | |
| 440 } | |
| 441 return BaseClass::LockRequest(options); | 378 return BaseClass::LockRequest(options); |
| 442 } | 379 } |
| 443 | 380 |
| 444 STDMETHODIMP WBPassthru::UnlockRequest() | 381 STDMETHODIMP WBPassthru::UnlockRequest() |
| 445 { | 382 { |
| 446 if (!m_hasOriginalStartCalled) | |
| 447 { | |
| 448 return S_OK; | |
| 449 } | |
| 450 return BaseClass::UnlockRequest(); | 383 return BaseClass::UnlockRequest(); |
| 451 } | 384 } |
| LEFT | RIGHT |