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

Delta Between Two Patch Sets: src/plugin/PluginWbPassThrough.cpp

Issue 4974480757620736: Issue #1356 - Improve detection of the issuer of the request (Closed)
Left Patch Set: Created Oct. 14, 2014, 11:23 p.m.
Right Patch Set: Rename the parameter Created Nov. 5, 2014, 4:51 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/plugin/PluginWbPassThrough.h ('k') | src/plugin/SinkPolicy.inl » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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
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
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 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld