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

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

Issue 4912420225024000: Issue #1234 - Convert strings associated with URL's (Closed)
Left Patch Set: Created Oct. 14, 2014, 10:17 p.m.
Right Patch Set: Created Jan. 5, 2015, 4:15 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
« src/plugin/PluginWbPassThrough.h ('K') | « src/plugin/PluginWbPassThrough.h ('k') | no next file » | 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 #include "PluginFilter.h" 6 #include "PluginFilter.h"
7 #include "PluginSettings.h" 7 #include "PluginSettings.h"
8 #include "PluginClass.h" 8 #include "PluginClass.h"
9 #include "PluginSystem.h" 9 #include "PluginSystem.h"
10 10 #include <WinInet.h>
11 #include "wtypes.h" 11 #include "wtypes.h"
12 12 #include "../shared/Utils.h"
13 EXTERN_C IMAGE_DOS_HEADER __ImageBase; 13
14 14 namespace
15 15 {
16 16 const std::string g_blockedByABPPage = "<!DOCTYPE html>"
17 int WBPassthruSink::GetContentTypeFromMimeType(CString mimeType) 17 "<html>"
18 "<body>"
19 "<!-- blocked by AdblockPlus -->"
20 "</body>"
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) || !winInetHttpInfo)
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 }
66
67 bool IsXmlHttpRequest(const std::wstring& additionalHeaders)
68 {
69 auto requestedWithHeader = ExtractHttpHeader<std::wstring>(additionalHeaders , L"X-Requested-With:", L"\n");
70 return TrimString(requestedWithHeader) == L"XMLHttpRequest";
71 }
72 }
73
74 WBPassthruSink::WBPassthruSink()
75 : m_currentPositionOfSentPage(0)
76 , m_contentType(CFilter::EContentType::contentTypeAny)
77 , m_isCustomResponse(false)
78 {
79 }
80
81 int WBPassthruSink::GetContentTypeFromMimeType(const CString& mimeType)
18 { 82 {
19 if (mimeType.Find(L"image/") >= 0) 83 if (mimeType.Find(L"image/") >= 0)
20 { 84 {
21 return CFilter::contentTypeImage; 85 return CFilter::contentTypeImage;
22 } 86 }
23 if (mimeType.Find(L"text/css") >= 0) 87 if (mimeType.Find(L"text/css") >= 0)
24 { 88 {
25 return CFilter::contentTypeStyleSheet; 89 return CFilter::contentTypeStyleSheet;
26 } 90 }
27 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0)) 91 if ((mimeType.Find(L"application/javascript") >= 0) || (mimeType.Find(L"applic ation/json") >= 0))
(...skipping 10 matching lines...) Expand all
38 } 102 }
39 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example 103 // It is important to have this check last, since it is rather generic, and mi ght overlay text/html, for example
40 if (mimeType.Find(L"xml") >= 0) 104 if (mimeType.Find(L"xml") >= 0)
41 { 105 {
42 return CFilter::contentTypeXmlHttpRequest; 106 return CFilter::contentTypeXmlHttpRequest;
43 } 107 }
44 108
45 return CFilter::contentTypeAny; 109 return CFilter::contentTypeAny;
46 } 110 }
47 111
48 int WBPassthruSink::GetContentTypeFromURL(std::wstring src) 112 int WBPassthruSink::GetContentTypeFromURL(const std::wstring& src)
sergei 2014/10/17 10:10:12 `const std::wstring&`
49 { 113 {
50 CString srcLegacy = ToCString(src); 114 CString srcLegacy = ToCString(src);
51 CString srcExt = srcLegacy; 115 CString srcExt = srcLegacy;
52 116
53 int pos = 0; 117 int pos = 0;
54 if ((pos = srcLegacy.Find('?')) > 0) 118 if ((pos = srcLegacy.Find('?')) > 0)
55 { 119 {
56 srcExt = srcLegacy.Left(pos); 120 srcExt = srcLegacy.Left(pos);
57 } 121 }
58 122
(...skipping 18 matching lines...) Expand all
77 return CFilter::contentTypeXmlHttpRequest; 141 return CFilter::contentTypeXmlHttpRequest;
78 } 142 }
79 else if (ext == L".swf") 143 else if (ext == L".swf")
80 { 144 {
81 return CFilter::contentTypeObject; 145 return CFilter::contentTypeObject;
82 } 146 }
83 else if (ext == L".jsp" || ext == L".php" || ext == L".html") 147 else if (ext == L".jsp" || ext == L".php" || ext == L".html")
84 { 148 {
85 return CFilter::contentTypeSubdocument; 149 return CFilter::contentTypeSubdocument;
86 } 150 }
87 else 151 return CFilter::contentTypeAny;
88 { 152 }
89 return CFilter::contentTypeAny & ~CFilter::contentTypeSubdocument; 153
90 } 154 int WBPassthruSink::GetContentType(const CString& mimeType, const std::wstring& domain, const std::wstring& src)
91
92 }
93
94 int WBPassthruSink::GetContentType(CString mimeType, std::wstring domain, std::w string src)
sergei 2014/10/17 10:10:12 const ATL::CString&, const std::wstring&
95 { 155 {
96 // No referer or mime type 156 // No referer or mime type
97 // BINDSTRING_XDR_ORIGIN works only for IE v8+ 157 // BINDSTRING_XDR_ORIGIN works only for IE v8+
98 if (mimeType.IsEmpty() && domain.empty() && CPluginClient::GetInstance()->GetI EVersion() >= 8) 158 if (mimeType.IsEmpty() && domain.empty() && CPluginClient::GetInstance()->GetI EVersion() >= 8)
99 { 159 {
100 return CFilter::contentTypeXmlHttpRequest; 160 return CFilter::contentTypeXmlHttpRequest;
101 } 161 }
102 int contentType = GetContentTypeFromMimeType(mimeType); 162 int contentType = GetContentTypeFromMimeType(mimeType);
103 if (contentType == CFilter::contentTypeAny) 163 if (contentType == CFilter::contentTypeAny)
104 { 164 {
105 contentType = GetContentTypeFromURL(src); 165 contentType = GetContentTypeFromURL(src);
106 } 166 }
107 return contentType; 167 return contentType;
108 } 168 }
109 169
110 //////////////////////////////////////////////////////////////////////////////// //////// 170 //////////////////////////////////////////////////////////////////////////////// ////////
111 //WBPassthruSink 171 //WBPassthruSink
112 //Monitor and/or cancel every request and responde 172 //Monitor and/or cancel every request and responde
113 //WB makes, including images, sounds, scripts, etc 173 //WB makes, including images, sounds, scripts, etc
114 //////////////////////////////////////////////////////////////////////////////// //////// 174 //////////////////////////////////////////////////////////////////////////////// ////////
115 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k, 175 HRESULT WBPassthruSink::OnStart(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSin k,
116 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved, 176 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HAN DLE_PTR dwReserved,
117 IInternetProtocol* pTargetProtocol) 177 IInternetProtocol* pTargetProtocol, bool& handle d)
118 { 178 {
119
120 m_pTargetProtocol = pTargetProtocol; 179 m_pTargetProtocol = pTargetProtocol;
121 bool isBlocked = false; 180 return BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTargetProtocol);
122 m_shouldBlock = false; 181 }
123 m_lastDataReported = false; 182
124 std::wstring src(szUrl); 183 HRESULT WBPassthruSink::OnRead(void* pv, ULONG cb, ULONG* pcbRead)
125 DEBUG_GENERAL(ToCString(src)); 184 {
126 UnescapeUrl(src); 185 if (!pv || !pcbRead)
127 186 {
128 std::wstring boundDomain; 187 return E_POINTER;
129 CString mimeType; 188 }
130 LPOLESTR mime[10]; 189 *pcbRead = 0;
131 if (pOIBindInfo) 190
132 { 191 if (PassthroughAPP::CustomSinkStartPolicy<WBPassthru, WBPassthruSink>::GetProt ocol(this)->m_shouldSupplyCustomContent)
133 ULONG resLen = 0; 192 {
134 193 ULONG blockedByABPPageSize = static_cast<ULONG>(g_blockedByABPPage.size());
135 // Apparently IE will report random mime type if there's more then 1 in the list. 194 auto positionGrow = std::min<ULONG>(cb, static_cast<ULONG>(blockedByABPPageS ize - m_currentPositionOfSentPage));
136 // So we get the whole list and just use the first one (top priority one) 195 if (positionGrow == 0) {
137 pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, mime, 10, &resLen); 196 return S_FALSE;
138 if (mime && resLen > 0) 197 }
139 { 198 std::copy(g_blockedByABPPage.begin(), g_blockedByABPPage.begin() + positionG row,
140 mimeType.SetString(mime[0]); 199 stdext::make_checked_array_iterator(static_cast<char*>(pv), cb));
141 } 200 *pcbRead = positionGrow;
142 LPOLESTR bindToObject = 0; 201 m_currentPositionOfSentPage += positionGrow;
143 pOIBindInfo->GetBindString(BINDSTRING_FLAG_BIND_TO_OBJECT, &bindToObject, 1, &resLen); 202
144 wchar_t* domainRetrieved = 0; 203 if (m_spInternetProtocolSink)
145 if (resLen == 0 || wcscmp(bindToObject, L"FALSE") == 0) 204 {
146 { 205 m_spInternetProtocolSink->ReportData(BSCF_INTERMEDIATEDATANOTIFICATION,
147 HRESULT hr = pOIBindInfo->GetBindString(BINDSTRING_XDR_ORIGIN, &domainRetr ieved, 1, &resLen); 206 static_cast<ULONG>(m_currentPositionOfSentPage), blockedByABPPageSize);
148 207 }
149 if ((hr == S_OK) && domainRetrieved && (resLen > 0)) 208 if (blockedByABPPageSize == m_currentPositionOfSentPage && m_spInternetProto colSink)
150 { 209 {
151 boundDomain = std::wstring(domainRetrieved); 210 m_spInternetProtocolSink->ReportData(BSCF_DATAFULLYAVAILABLE, blockedByABP PageSize, blockedByABPPageSize);
152 } 211 m_spInternetProtocolSink->ReportResult(S_OK, 0, nullptr);
153 }
154 }
155
156 CString cookie;
157 ULONG len1 = 2048;
158 ULONG len2 = 2048;
159
160 int contentType = CFilter::contentTypeAny;
161
162 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
163 CPluginClient* client = CPluginClient::GetInstance();
164
165
166 if (tab && client)
167 {
168 std::wstring documentUrl = tab->GetDocumentUrl();
169 // Page is identical to document => don't block
170 if (documentUrl == src)
171 {
172 // fall through
173 }
174 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(documentUrl))
175 {
176 boundDomain = tab->GetDocumentUrl();
177 contentType = CFilter::contentTypeAny;
178 if ((tab != 0) && (tab->IsFrameCached(src)))
179 {
180 contentType = CFilter::contentTypeSubdocument;
181 }
182 else
183 {
184 contentType = GetContentType(mimeType, boundDomain, src);
185 }
186 if (client->ShouldBlock(src, contentType, boundDomain, true))
187 {
188 isBlocked = true;
189 DEBUG_BLOCKER("Blocker::Blocking Http-request:" + ToCString(src));
190 }
191 }
192 if (!isBlocked)
193 {
194 DEBUG_BLOCKER("Blocker::Ignoring Http-request:" + ToCString(src))
195 }
196 }
197
198
199 if (tab == NULL)
200 {
201 contentType = GetContentType(mimeType, boundDomain, src);
202 if (client->ShouldBlock(src, contentType, boundDomain, true))
203 {
204 isBlocked = true;
205 }
206 }
207
208 #ifdef _DEBUG
209 CString type;
210
211 if (contentType == CFilter::contentTypeDocument) type = "DOCUMENT";
212 else if (contentType == CFilter::contentTypeObject) type = "OBJECT";
213 else if (contentType == CFilter::contentTypeImage) type = "IMAGE";
214 else if (contentType == CFilter::contentTypeScript) type = "SCRIPT";
215 else if (contentType == CFilter::contentTypeOther) type = "OTHER";
216 else if (contentType == CFilter::contentTypeUnknown) type = "OTHER";
217 else if (contentType == CFilter::contentTypeSubdocument) type = "SUBDOCUMENT";
218 else if (contentType == CFilter::contentTypeStyleSheet) type = "STYLESHEET";
219 else type = "OTHER";
220
221 if (isBlocked)
222 {
223 CPluginDebug::DebugResultBlocking(type, src, boundDomain);
224 }
225 else
226 {
227 CPluginDebug::DebugResultIgnoring(type, src, boundDomain);
228 }
229 #endif
230
231 //Fixes the iframe back button issue
232 if (client->GetIEVersion() > 6)
233 {
234 if ((contentType == CFilter::contentTypeImage) && (isBlocked))
235 {
236 m_shouldBlock = true;
237 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
238
239 return INET_E_REDIRECT_FAILED;
240
241 }
242 if (((contentType == CFilter::contentTypeSubdocument))&& (isBlocked))
243 {
244 m_shouldBlock = true;
245 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
246
247 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/html");
248
249 //Here we check if we are running on Windows 8 Consumer Preview.
250 //For some reason on that environment the next line causes IE to crash
251 if (CPluginSettings::GetInstance()->GetWindowsBuildNumber() != 8250)
252 {
253 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECT_FAILED, 0, szUrl) ;
254 }
255
256 return INET_E_REDIRECT_FAILED;
257 }
258 if (((contentType == CFilter::contentTypeScript)) && (isBlocked))
259 {
260 m_shouldBlock = true;
261 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
262 m_spInternetProtocolSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"t ext/javascript");
263 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
264 return INET_E_REDIRECT_FAILED;
265 }
266 if ((contentType == CFilter::contentTypeXmlHttpRequest) && (isBlocked))
267 {
268 m_shouldBlock = true;
269 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
270 m_spInternetProtocolSink->ReportResult(INET_E_REDIRECTING, 301, L"data:");
271 return INET_E_REDIRECT_FAILED;
272 }
273 if ((isBlocked))
274 {
275 m_shouldBlock = true;
276 BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, pTa rgetProtocol);
277 m_spInternetProtocolSink->ReportResult(S_FALSE, 0, L"");
278
279 return INET_E_REDIRECT_FAILED;
280 }
281 }
282 return isBlocked ? S_FALSE : BaseClass::OnStart(szUrl, pOIProtSink, pOIBindInf o, grfPI, dwReserved, pTargetProtocol);
283 }
284
285
286 HRESULT WBPassthruSink::Read(void *pv, ULONG cb, ULONG* pcbRead)
287 {
288 if (m_shouldBlock)
289 {
290 *pcbRead = 0;
291 if (!m_lastDataReported)
292 {
293 if (cb <= 1)
294 {
295 //IE must've gone nuts if this happened, but let's be cool about it and report we have no more data
296 m_spInternetProtocolSink->ReportResult(S_FALSE, 0, NULL);
297 return S_FALSE;
298 }
299 *pcbRead = 1;
300 memcpy(pv, " ", 1);
301
302 if (m_spInternetProtocolSink != NULL)
303 {
304 m_spInternetProtocolSink->ReportResult(S_OK, 0, NULL);
305 }
306 m_lastDataReported = true;
307 m_shouldBlock = false;
308 return S_OK;
309 } 212 }
310 return S_OK; 213 return S_OK;
311 } 214 }
312 else 215 return m_pTargetProtocol->Read(pv, cb, pcbRead);
313 {
314
315 return m_pTargetProtocol->Read(pv, cb, pcbRead);
316 }
317 return S_OK;
318 } 216 }
319 STDMETHODIMP WBPassthruSink::Switch( 217 STDMETHODIMP WBPassthruSink::Switch(
320 /* [in] */ PROTOCOLDATA *pProtocolData) 218 /* [in] */ PROTOCOLDATA *pProtocolData)
321 { 219 {
322 ATLASSERT(m_spInternetProtocolSink != 0); 220 ATLASSERT(m_spInternetProtocolSink != 0);
323 221
324 /* 222 /*
325 From Igor Tandetnik "itandetnik@mvps.org" 223 From Igor Tandetnik "itandetnik@mvps.org"
326 " 224 "
327 Beware multithreading. URLMon has this nasty habit of spinning worker 225 Beware multithreading. URLMon has this nasty habit of spinning worker
328 threads, not even bothering to initialize COM on them, and calling APP 226 threads, not even bothering to initialize COM on them, and calling APP
329 methods on those threads. If you try to raise COM events directly from 227 methods on those threads. If you try to raise COM events directly from
330 such a thread, bad things happen (random crashes, events being lost). 228 such a thread, bad things happen (random crashes, events being lost).
331 You are only guaranteed to be on the main STA thread in two cases. 229 You are only guaranteed to be on the main STA thread in two cases.
332 First, in methods of interfaces that were obtained with 230 First, in methods of interfaces that were obtained with
333 IServiceProvider, such as IHttpNegotiage::BeginningTransaction or 231 IServiceProvider, such as IHttpNegotiage::BeginningTransaction or
334 IAuthenticate::Authenticate. Second, you can call 232 IAuthenticate::Authenticate. Second, you can call
335 IInternetProtocolSink::Switch with PD_FORCE_SWITCH flag in 233 IInternetProtocolSink::Switch with PD_FORCE_SWITCH flag in
336 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call 234 PROTOCOLDATA::grfFlags, eventually URLMon will turn around and call
337 IInternetProtocol::Continue on the main thread. 235 IInternetProtocol::Continue on the main thread.
338 236
339 Or, if you happen to have a window handy that was created on the main 237 Or, if you happen to have a window handy that was created on the main
340 thread, you can post yourself a message. 238 thread, you can post yourself a message.
341 " 239 "
342 */ 240 */
343 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED; 241 return m_spInternetProtocolSink ? m_spInternetProtocolSink->Switch(pProtocolDa ta) : E_UNEXPECTED;
344 } 242 }
345 243
346 244 // This is the heuristic which detects the requests issued by Flash.ocx.
347 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) 245 // It turned out that the implementation from ''Flash.ocx'' (tested version is 1 5.0.0.152)
348 { 246 // returns quite minimal configuration in comparison with the implementation fro m Microsofts'
247 // libraries (see grfBINDF and bindInfo.dwOptions). The impl from MS often inclu des something
248 // else.
249 bool WBPassthruSink::IsFlashRequest(const wchar_t* const* additionalHeaders)
250 {
251 if (additionalHeaders && *additionalHeaders)
252 {
253 auto flashVersionHeader = ExtractHttpHeader<std::wstring>(*additionalHeaders , L"x-flash-version:", L"\n");
254 if (!TrimString(flashVersionHeader).empty())
255 {
256 return true;
257 }
258 }
259 ATL::CComPtr<IBindStatusCallback> bscb;
260 if (SUCCEEDED(QueryServiceFromClient(&bscb)) && !!bscb)
261 {
262 DWORD grfBINDF = 0;
263 BINDINFO bindInfo = {};
264 bindInfo.cbSize = sizeof(bindInfo);
265 if (SUCCEEDED(bscb->GetBindInfo(&grfBINDF, &bindInfo)) &&
266 (BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE| BINDF_PULLDATA) == grfBINDF &&
267 (BINDINFO_OPTIONS_ENABLE_UTF8 | BINDINFO_OPTIONS_USE_IE_ENCODING) == bindI nfo.dwOptions
268 )
269 {
270 return true;
271 }
272 }
273 return false;
274 }
275
276 STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeade rs, DWORD dwReserved, LPWSTR* pszAdditionalHeaders)
277 {
278 if (!szURL)
279 {
280 return E_POINTER;
281 }
282 std::wstring src = szURL;
283 DEBUG_GENERAL(ToCString(src));
284
285 std::string acceptHeader = ExtractHttpAcceptHeader(m_spTargetProtocol);
286 m_contentType = GetContentTypeFromMimeType(ATL::CString(acceptHeader.c_str())) ;
287
349 if (pszAdditionalHeaders) 288 if (pszAdditionalHeaders)
350 { 289 {
351 *pszAdditionalHeaders = 0; 290 *pszAdditionalHeaders = nullptr;
291 }
292
293 CComPtr<IHttpNegotiate> httpNegotiate;
294 QueryServiceFromClient(&httpNegotiate);
295 // This fills the pszAdditionalHeaders with more headers. One of which is the Referer header, which we need.
296 // There doesn't seem to be any other way to get this header before the reques t has been made.
297 HRESULT nativeHr = httpNegotiate ? httpNegotiate->BeginningTransaction(szURL, szHeaders, dwReserved, pszAdditionalHeaders) : S_OK;
298
299 if (pszAdditionalHeaders && *pszAdditionalHeaders)
300 {
301 m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Ref erer:", L"\n");
302 }
303 m_boundDomain = TrimString(m_boundDomain);
304 CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId());
305 CPluginClient* client = CPluginClient::GetInstance();
306
307 if (tab && client)
308 {
309 std::wstring documentUrl = tab->GetDocumentUrl();
310 // Page is identical to document => don't block
311 if (documentUrl == src)
312 {
313 return nativeHr;
314 }
315 else if (CPluginSettings::GetInstance()->IsPluginEnabled() && !client->IsWhi telistedUrl(documentUrl))
316 {
317 if (tab->IsFrameCached(src))
318 {
319 m_contentType = CFilter::contentTypeSubdocument;
320 }
321 }
322 }
323
324 if (IsFlashRequest(pszAdditionalHeaders))
325 {
326 m_contentType = CFilter::EContentType::contentTypeObjectSubrequest;
327 }
328
329 if (pszAdditionalHeaders && *pszAdditionalHeaders && IsXmlHttpRequest(*pszAddi tionalHeaders))
330 {
331 m_contentType = CFilter::EContentType::contentTypeXmlHttpRequest;
332 }
333
334 if (client->ShouldBlock(szURL, m_contentType, m_boundDomain, /*debug flag but must be set*/true))
335 {
336 // NOTE: Feeding custom HTML to Flash, instead of original object subrequest
337 // doesn't have much sense. It also can manifest in unwanted result»
338 // like video being blocked (See https://issues.adblockplus.org/ticket/1669) »
339 // So we report blocked object subrequests as failed, not just empty HTML.
340 m_isCustomResponse = m_contentType != CFilter::contentTypeObjectSubrequest;
341 return E_ABORT;
342 }
343 return nativeHr;
344 }
345
346 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
347 {
348 if (pszAdditionalRequestHeaders)
349 {
350 *pszAdditionalRequestHeaders = 0;
352 } 351 }
353 352
354 CComPtr<IHttpNegotiate> spHttpNegotiate; 353 CComPtr<IHttpNegotiate> spHttpNegotiate;
355 QueryServiceFromClient(&spHttpNegotiate); 354 QueryServiceFromClient(&spHttpNegotiate);
356 return spHttpNegotiate ? spHttpNegotiate->BeginningTransaction(szURL, szHeader s,dwReserved, pszAdditionalHeaders) : S_OK;
357 }
358
359 STDMETHODIMP WBPassthruSink::OnResponse(DWORD dwResponseCode, LPCWSTR szResponse Headers, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
360 {
361 if (pszAdditionalRequestHeaders)
362 {
363 *pszAdditionalRequestHeaders = 0;
364 }
365
366 CComPtr<IHttpNegotiate> spHttpNegotiate;
367 QueryServiceFromClient(&spHttpNegotiate);
368 355
369 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK; 356 return spHttpNegotiate ? spHttpNegotiate->OnResponse(dwResponseCode, szRespons eHeaders, szRequestHeaders, pszAdditionalRequestHeaders) : S_OK;
370 } 357 }
371 358
372 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus Text) 359 STDMETHODIMP WBPassthruSink::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatus Text)
373 { 360 {
374 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS tatusCode, szStatusText) : S_OK; 361 return m_spInternetProtocolSink ? m_spInternetProtocolSink->ReportProgress(ulS tatusCode, szStatusText) : S_OK;
375 } 362 }
376 363
364 STDMETHODIMP WBPassthruSink::ReportResult(/* [in] */ HRESULT hrResult, /* [in] * / DWORD dwError, /* [in] */ LPCWSTR szResult)
365 {
366 if (m_isCustomResponse)
367 {
368 // Don't notify the client about aborting of the operation, thus don't call BaseClass::ReportResult.
369 // Current method is called by the original protocol implementation and we a re intercepting the
370 // call here and eating it, we will call the proper ReportResult later by ou rself.
371 return S_OK;
372 }
373 return BaseClass::ReportResult(hrResult, dwError, szResult);
374 }
375
376
377 WBPassthru::WBPassthru()
378 : m_shouldSupplyCustomContent(false)
379 {
380 }
377 381
378 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink , 382 STDMETHODIMP WBPassthru::Start(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink ,
379 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) 383 IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved)
380 { 384 {
381 ATLASSERT(m_spInternetProtocol != 0); 385 ATLASSERT(m_spInternetProtocol != 0);
382 if (!m_spInternetProtocol) 386 if (!m_spInternetProtocol)
383 { 387 {
384 return E_UNEXPECTED; 388 return E_UNEXPECTED;
385 } 389 }
386 390
387 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, 391 return OnStart(szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved, m_spInterne tProtocol);
388 dwReserved, m_spInternetProtocol); 392 }
389 } 393
390 394 STDMETHODIMP WBPassthru::Read(/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [o ut] */ ULONG *pcbRead)
391 STDMETHODIMP WBPassthru::Read(»/* [in, out] */ void *pv,/* [in] */ ULONG cb,/* [out] */ ULONG *pcbRead) 395 {
392 { 396 WBPassthruSink* pSink = GetSink();
393 397 return pSink->OnRead(pv, cb, pcbRead);
394 WBPassthruSink* pSink = GetSink(); 398 }
395 return pSink->Read(pv, cb, pcbRead);
396 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld