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 all issues Created May 23, 2013, 12:29 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
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: pipeName, bufferSize, AutoHandle, ReadMessage, WriteMessage, MarshalS trings and UnmarshalStrings are
18 // duplicated in AdblockPlusEngine. We should find a way to reuse them.
19
20 const std::wstring pipeName = L"\\\\.\\pipe\\adblockplusengine";
21 const int bufferSize = 1024;
22
23 class AutoHandle
24 {
25 public:
26 AutoHandle()
27 {
28 }
29
30 AutoHandle(HANDLE handle) : handle(handle)
31 {
32 }
33
34 ~AutoHandle()
35 {
36 CloseHandle(handle);
37 }
38
39 HANDLE get()
40 {
41 return handle;
42 }
43
44 private:
45 HANDLE handle;
46
47 AutoHandle(const AutoHandle& autoHandle);
48 AutoHandle& operator=(const AutoHandle& autoHandle);
49 };
50
51 std::string MarshalStrings(const std::vector<std::string>& strings)
52 {
53 // TODO: This is some pretty hacky marshalling, replace it with something mo re robust
54 std::string marshalledStrings;
55 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st rings.end(); it++)
56 marshalledStrings += *it + ';';
57 return marshalledStrings;
58 }
59
60 std::vector<std::string> UnmarshalStrings(const std::string& message)
61 {
62 std::stringstream stream(message);
63 std::vector<std::string> strings;
64 std::string string;
65 while (std::getline(stream, string, ';'))
66 strings.push_back(string);
67 return strings;
68 }
69
70 std::string ReadMessage(HANDLE pipe)
71 {
72 std::stringstream stream;
73 std::auto_ptr<char> buffer(new char[bufferSize]);
74 bool doneReading = false;
75 while (!doneReading)
76 {
77 DWORD bytesRead;
78 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0) )
79 doneReading = true;
80 else if (GetLastError() != ERROR_MORE_DATA)
81 {
82 std::stringstream stream;
83 stream << "Error reading from pipe: " << GetLastError();
84 throw std::runtime_error(stream.str());
85 }
86 stream << std::string(buffer.get(), bytesRead);
87 }
88 return stream.str();
89 }
90
91 void WriteMessage(HANDLE pipe, const std::string& message)
92 {
93 DWORD bytesWritten;
94 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0))
95 throw std::runtime_error("Failed to write to pipe");
96 }
97
98 HANDLE OpenPipe(const std::wstring& name)
99 {
100 if (WaitNamedPipe(name.c_str(), 5000))
101 return CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_E XISTING, 0, 0);
102 return INVALID_HANDLE_VALUE;
103 }
104
105 void SpawnAdblockPlusEngine()
106 {
107 std::wstring engineExecutablePath = DllDir() + L"AdblockPlusEngine.exe";
108 STARTUPINFO startupInfo = {};
109 PROCESS_INFORMATION processInformation = {};
110
111 HANDLE token;
112 OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
113 HANDLE newToken;
114 DuplicateTokenEx(token, 0, 0, SecurityImpersonation, TokenPrimary, &newToken );
115
116 if (!CreateProcessAsUser(newToken, 0, const_cast<wchar_t*>(engineExecutableP ath.c_str()), 0, 0, 0, 0, 0, 0,
117 &startupInfo, &processInformation))
118 {
119 DWORD error = GetLastError();
120 throw std::runtime_error("Failed to start Adblock Plus Engine");
121 }
122
123 CloseHandle(processInformation.hProcess);
124 CloseHandle(processInformation.hThread);
125 }
126
127 HANDLE OpenAdblockPlusEnginePipe()
128 {
129 try
130 {
131 HANDLE pipe = OpenPipe(pipeName);
132 if (pipe == INVALID_HANDLE_VALUE)
133 {
134 SpawnAdblockPlusEngine();
135
136 int timeout = 10000;
137 while ((pipe = OpenPipe(pipeName)) == INVALID_HANDLE_VALUE)
138 {
139 const int step = 10;
140 Sleep(step);
141 timeout -= step;
142 if (timeout <= 0)
143 throw std::runtime_error("Unable to open Adblock Plus Engine pipe");
144 }
145 }
146
147 DWORD mode = PIPE_READMODE_MESSAGE;
148 if (!SetNamedPipeHandleState(pipe, &mode, 0, 0))
149 throw std::runtime_error("SetNamedPipeHandleState failed");
150
151 return pipe;
152 }
153 catch(std::exception e)
154 {
155 DEBUG_GENERAL(e.what());
156 return INVALID_HANDLE_VALUE;
157 }
158 }
159 }
14 160
15 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL; 161 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL;
16 162
17
18 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase() 163 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase()
19 { 164 {
20 try 165 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
21 { 166 }
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 167
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() 168 CAdblockPlusClient::~CAdblockPlusClient()
41 { 169 {
42 s_instance = NULL; 170 s_instance = NULL;
43 } 171 }
44 172
45 173
46 CAdblockPlusClient* CAdblockPlusClient::GetInstance() 174 CAdblockPlusClient* CAdblockPlusClient::GetInstance()
47 { 175 {
48 CAdblockPlusClient* instance = NULL; 176 CAdblockPlusClient* instance = NULL;
49 177
50 s_criticalSectionLocal.Lock(); 178 s_criticalSectionLocal.Lock();
51 { 179 {
52 if (!s_instance) 180 if (!s_instance)
53 { 181 {
54 CAdblockPlusClient* client = new CAdblockPlusClient(); 182 CAdblockPlusClient* client = new CAdblockPlusClient();
55 183
56 s_instance = client; 184 s_instance = client;
57 } 185 }
58 186
59 instance = s_instance; 187 instance = s_instance;
60 } 188 }
61 s_criticalSectionLocal.Unlock(); 189 s_criticalSectionLocal.Unlock();
62 190
63 return instance; 191 return instance;
64 } 192 }
65 193
66 AdblockPlus::FilterEngine* CAdblockPlusClient::GetFilterEngine()
67 {
68 return filterEngine.get();
69 }
70 194
71 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString & domain, bool addDebug) 195 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString & domain, bool addDebug)
72 { 196 {
73 bool isBlocked = false; 197 bool isBlocked = false;
74 198
75 bool isCached = false; 199 bool isCached = false;
76 200
77 CPluginSettings* settings = CPluginSettings::GetInstance(); 201 CPluginSettings* settings = CPluginSettings::GetInstance();
78 202
79 m_criticalSectionCache.Lock(); 203 m_criticalSectionCache.Lock();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 BYTE version[50]; 280 BYTE version[50];
157 cbData = 50; 281 cbData = 50;
158 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a); 282 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a);
159 if (status != 0) 283 if (status != 0)
160 { 284 {
161 return 0; 285 return 0;
162 } 286 }
163 RegCloseKey(hKey); 287 RegCloseKey(hKey);
164 return (int)(version[0] - 48); 288 return (int)(version[0] - 48);
165 } 289 }
290
291 std::string CallAdblockPlusEngineProcedure(const std::string& name, const std::v ector<std::string>& args)
292 {
293 AutoHandle pipe(OpenAdblockPlusEnginePipe());
294 std::vector<std::string> strings;
295 strings.push_back(name);
296 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.en d(); it++)
297 strings.push_back(*it);
298 WriteMessage(pipe.get(), MarshalStrings(strings));
299 return ReadMessage(pipe.get());
300 }
301
302 bool CAdblockPlusClient::Matches(const std::string& url, const std::string& cont entType, const std::string& domain)
303 {
304 std::vector<std::string> args;
305 args.push_back(url);
306 args.push_back(contentType);
307 args.push_back(domain);
308
309 try
310 {
311 std::string response = CallAdblockPlusEngineProcedure("Matches", args);
312 return response == "1";
313 }
314 catch (const std::exception& e)
315 {
316 DEBUG_GENERAL(e.what());
317 return false;
318 }
319 }
320
321 std::vector<std::string> CAdblockPlusClient::GetElementHidingSelectors(std::stri ng domain)
322 {
323 std::vector<std::string> args;
324 args.push_back(domain);
325
326 try
327 {
328 std::string response = CallAdblockPlusEngineProcedure("GetElementHidingSelec tors", args);
329 return UnmarshalStrings(response);
330 }
331 catch (const std::exception& e)
332 {
333 DEBUG_GENERAL(e.what());
334 return std::vector<std::string>();
335 }
336 }
337
338 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::FetchAvailableSubs criptions()
339 {
340 //TODO: implement this
341 return std::vector<AdblockPlus::SubscriptionPtr>();
342 }
343
344 std::vector<AdblockPlus::FilterPtr> CAdblockPlusClient::GetListedFilters()
345 {
346 //TODO: implement this
347 return std::vector<AdblockPlus::FilterPtr>();
348 }
349
350 AdblockPlus::FilterPtr CAdblockPlusClient::GetFilter(std::string text)
351 {
352 //TODO: implement this
353 return AdblockPlus::FilterPtr();
354 }
355
356 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::GetListedSubscript ions()
357 {
358 //TODO: implement this
359 return std::vector<AdblockPlus::SubscriptionPtr>();
360 }
361
362 AdblockPlus::SubscriptionPtr CAdblockPlusClient::GetSubscription(std::string url )
363 {
364 //TODO: imlement this
365 return AdblockPlus::SubscriptionPtr();
366 }
OLDNEW

Powered by Google App Engine
This is Rietveld