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 |