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

Side by Side Diff: Shared/AdblockPlusClient.cpp

Issue 10580043: Run a single FilterEngine instance in a separate process (Closed)
Patch Set: Addressed review issues Created May 23, 2013, 7:10 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Shared/AdblockPlusClient.h ('k') | Shared/PluginFilter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "PluginStdAfx.h" 1 #include "PluginStdAfx.h"
2 2
3 #include "PluginSettings.h" 3 #include "PluginSettings.h"
4 #include "PluginSystem.h" 4 #include "PluginSystem.h"
5 #include "PluginFilter.h" 5 #include "PluginFilter.h"
6 #include "PluginClientFactory.h" 6 #include "PluginClientFactory.h"
7 #include "PluginDictionary.h" 7 #include "PluginDictionary.h"
8 #include "PluginHttpRequest.h" 8 #include "PluginHttpRequest.h"
9 #include "PluginMutex.h" 9 #include "PluginMutex.h"
10 #include "PluginClass.h" 10 #include "PluginClass.h"
11 #include "PluginUtil.h"
11 12
12 #include "AdblockPlusClient.h" 13 #include "AdblockPlusClient.h"
13 14
15 namespace
16 {
17 // TODO: GetUserName, pipeName, bufferSize, AutoHandle, ReadMessage, WriteMess age, MarshalStrings and UnmarshalStrings are
18 // duplicated in AdblockPlusEngine. We should find a way to reuse them.
19
20 std::wstring GetUserName()
21 {
22 const DWORD maxLength = UNLEN + 1;
23 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]);
24 DWORD length = maxLength;
25 if (!::GetUserName(buffer.get(), &length))
26 {
27 std::stringstream stream;
28 stream << "Failed to get the current user's name (Error code: " << GetLast Error() << ")";
29 throw std::runtime_error("Failed to get the current user's name");
30 }
31 return std::wstring(buffer.get(), length);
32 }
33
34 const std::wstring pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName ();
35 const int bufferSize = 1024;
36
37 class AutoHandle
38 {
39 public:
40 AutoHandle()
41 {
42 }
43
44 AutoHandle(HANDLE handle) : handle(handle)
45 {
46 }
47
48 ~AutoHandle()
49 {
50 CloseHandle(handle);
51 }
52
53 HANDLE get()
54 {
55 return handle;
56 }
57
58 private:
59 HANDLE handle;
60
61 AutoHandle(const AutoHandle& autoHandle);
62 AutoHandle& operator=(const AutoHandle& autoHandle);
63 };
64
65 std::string MarshalStrings(const std::vector<std::string>& strings)
66 {
67 // TODO: This is some pretty hacky marshalling, replace it with something mo re robust
68 std::string marshalledStrings;
69 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st rings.end(); it++)
70 marshalledStrings += *it + ';';
71 return marshalledStrings;
72 }
73
74 std::vector<std::string> UnmarshalStrings(const std::string& message)
75 {
76 std::stringstream stream(message);
77 std::vector<std::string> strings;
78 std::string string;
79 while (std::getline(stream, string, ';'))
80 strings.push_back(string);
81 return strings;
82 }
83
84 std::string ReadMessage(HANDLE pipe)
85 {
86 std::stringstream stream;
87 std::auto_ptr<char> buffer(new char[bufferSize]);
88 bool doneReading = false;
89 while (!doneReading)
90 {
91 DWORD bytesRead;
92 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0) )
93 doneReading = true;
94 else if (GetLastError() != ERROR_MORE_DATA)
95 {
96 std::stringstream stream;
97 stream << "Error reading from pipe: " << GetLastError();
98 throw std::runtime_error(stream.str());
99 }
100 stream << std::string(buffer.get(), bytesRead);
101 }
102 return stream.str();
103 }
104
105 void WriteMessage(HANDLE pipe, const std::string& message)
106 {
107 DWORD bytesWritten;
108 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0))
109 throw std::runtime_error("Failed to write to pipe");
110 }
111
112 HANDLE OpenPipe(const std::wstring& name)
113 {
114 if (WaitNamedPipe(name.c_str(), 5000))
115 return CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_E XISTING, 0, 0);
116 return INVALID_HANDLE_VALUE;
117 }
118
119 void SpawnAdblockPlusEngine()
120 {
121 std::wstring engineExecutablePath = DllDir() + L"AdblockPlusEngine.exe";
122 STARTUPINFO startupInfo = {};
123 PROCESS_INFORMATION processInformation = {};
124
125 HANDLE token;
126 OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
127 HANDLE newToken;
128 DuplicateTokenEx(token, 0, 0, SecurityImpersonation, TokenPrimary, &newToken );
129
130 if (!CreateProcessAsUser(newToken, 0, const_cast<wchar_t*>(engineExecutableP ath.c_str()), 0, 0, 0, 0, 0, 0,
131 &startupInfo, &processInformation))
132 {
133 DWORD error = GetLastError();
134 throw std::runtime_error("Failed to start Adblock Plus Engine");
135 }
136
137 CloseHandle(processInformation.hProcess);
138 CloseHandle(processInformation.hThread);
139 }
140
141 HANDLE OpenAdblockPlusEnginePipe()
142 {
143 try
144 {
145 HANDLE pipe = OpenPipe(pipeName);
146 if (pipe == INVALID_HANDLE_VALUE)
147 {
148 SpawnAdblockPlusEngine();
149
150 int timeout = 10000;
151 while ((pipe = OpenPipe(pipeName)) == INVALID_HANDLE_VALUE)
152 {
153 const int step = 10;
154 Sleep(step);
155 timeout -= step;
156 if (timeout <= 0)
157 throw std::runtime_error("Unable to open Adblock Plus Engine pipe");
158 }
159 }
160
161 DWORD mode = PIPE_READMODE_MESSAGE;
162 if (!SetNamedPipeHandleState(pipe, &mode, 0, 0))
163 throw std::runtime_error("SetNamedPipeHandleState failed");
164
165 return pipe;
166 }
167 catch(std::exception e)
168 {
169 DEBUG_GENERAL(e.what());
170 return INVALID_HANDLE_VALUE;
171 }
172 }
173 }
14 174
15 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL; 175 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL;
16 176
17
18 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase() 177 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase()
19 { 178 {
20 try 179 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
21 { 180 }
22 DEBUG_GENERAL("Building client");
23 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
24 AdblockPlus::AppInfo appInfo;
25 appInfo.name = "adblockplusie";
26 appInfo.version = CT2CA(_T(IEPLUGIN_VERSION), CP_UTF8);
27 appInfo.platform = "msie";
28
29 DEBUG_GENERAL(L"Building engine");
30 181
31 JsEnginePtr jsEngine(AdblockPlus::JsEngine::New(appInfo));
32 filterEngine = std::auto_ptr<AdblockPlus::FilterEngine>(new AdblockPlus::Fil terEngine(jsEngine));
33
34 }
35 catch(std::exception ex)
36 {
37 DEBUG_GENERAL(ex.what());
38 }
39 }
40 CAdblockPlusClient::~CAdblockPlusClient() 182 CAdblockPlusClient::~CAdblockPlusClient()
41 { 183 {
42 s_instance = NULL; 184 s_instance = NULL;
43 } 185 }
44 186
45 187
46 CAdblockPlusClient* CAdblockPlusClient::GetInstance() 188 CAdblockPlusClient* CAdblockPlusClient::GetInstance()
47 { 189 {
48 CAdblockPlusClient* instance = NULL; 190 CAdblockPlusClient* instance = NULL;
49 191
50 s_criticalSectionLocal.Lock(); 192 s_criticalSectionLocal.Lock();
51 { 193 {
52 if (!s_instance) 194 if (!s_instance)
53 { 195 {
54 CAdblockPlusClient* client = new CAdblockPlusClient(); 196 CAdblockPlusClient* client = new CAdblockPlusClient();
55 197
56 s_instance = client; 198 s_instance = client;
57 } 199 }
58 200
59 instance = s_instance; 201 instance = s_instance;
60 } 202 }
61 s_criticalSectionLocal.Unlock(); 203 s_criticalSectionLocal.Unlock();
62 204
63 return instance; 205 return instance;
64 } 206 }
65 207
66 AdblockPlus::FilterEngine* CAdblockPlusClient::GetFilterEngine()
67 {
68 return filterEngine.get();
69 }
70 208
71 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString & domain, bool addDebug) 209 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString & domain, bool addDebug)
72 { 210 {
73 bool isBlocked = false; 211 bool isBlocked = false;
74 212
75 bool isCached = false; 213 bool isCached = false;
76 214
77 CPluginSettings* settings = CPluginSettings::GetInstance(); 215 CPluginSettings* settings = CPluginSettings::GetInstance();
78 216
79 m_criticalSectionCache.Lock(); 217 m_criticalSectionCache.Lock();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 BYTE version[50]; 294 BYTE version[50];
157 cbData = 50; 295 cbData = 50;
158 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a); 296 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a);
159 if (status != 0) 297 if (status != 0)
160 { 298 {
161 return 0; 299 return 0;
162 } 300 }
163 RegCloseKey(hKey); 301 RegCloseKey(hKey);
164 return (int)(version[0] - 48); 302 return (int)(version[0] - 48);
165 } 303 }
304
305 std::string CallAdblockPlusEngineProcedure(const std::vector<std::string>& args)
306 {
307 AutoHandle pipe(OpenAdblockPlusEnginePipe());
308 WriteMessage(pipe.get(), MarshalStrings(args));
309 return ReadMessage(pipe.get());
310 }
311
312 bool CAdblockPlusClient::Matches(const std::string& url, const std::string& cont entType, const std::string& domain)
313 {
314 std::vector<std::string> args;
315 args.push_back("Matches");
316 args.push_back(url);
317 args.push_back(contentType);
318 args.push_back(domain);
319
320 try
321 {
322 std::string response = CallAdblockPlusEngineProcedure(args);
323 return response == "1";
324 }
325 catch (const std::exception& e)
326 {
327 DEBUG_GENERAL(e.what());
328 return false;
329 }
330 }
331
332 std::vector<std::string> CAdblockPlusClient::GetElementHidingSelectors(std::stri ng domain)
333 {
334 std::vector<std::string> args;
335 args.push_back("GetElementHidingSelectors");
336 args.push_back(domain);
337
338 try
339 {
340 std::string response = CallAdblockPlusEngineProcedure(args);
341 return UnmarshalStrings(response);
342 }
343 catch (const std::exception& e)
344 {
345 DEBUG_GENERAL(e.what());
346 return std::vector<std::string>();
347 }
348 }
349
350 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::FetchAvailableSubs criptions()
351 {
352 //TODO: implement this
353 return std::vector<AdblockPlus::SubscriptionPtr>();
354 }
355
356 std::vector<AdblockPlus::FilterPtr> CAdblockPlusClient::GetListedFilters()
357 {
358 //TODO: implement this
359 return std::vector<AdblockPlus::FilterPtr>();
360 }
361
362 AdblockPlus::FilterPtr CAdblockPlusClient::GetFilter(std::string text)
363 {
364 //TODO: implement this
365 return AdblockPlus::FilterPtr();
366 }
367
368 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::GetListedSubscript ions()
369 {
370 //TODO: implement this
371 return std::vector<AdblockPlus::SubscriptionPtr>();
372 }
373
374 AdblockPlus::SubscriptionPtr CAdblockPlusClient::GetSubscription(std::string url )
375 {
376 //TODO: imlement this
377 return AdblockPlus::SubscriptionPtr();
378 }
OLDNEW
« no previous file with comments | « Shared/AdblockPlusClient.h ('k') | Shared/PluginFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld