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

Side by Side Diff: compiled/subscription/DownloadableSubscription.cpp

Issue 29630576: Issue 5146 - Part 2: Process http response in C++ (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Rebased Created Dec. 5, 2017, 6:09 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 | « compiled/subscription/DownloadableSubscription.h ('k') | lib/synchronizer.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 param.first.toLower(); 79 param.first.toLower();
80 param.second = DependentString( 80 param.second = DependentString(
81 text, beginValue, text.length() - beginValue); 81 text, beginValue, text.length() - beginValue);
82 } 82 }
83 } 83 }
84 return param; 84 return param;
85 } 85 }
86 } 86 }
87 87
88 DownloadableSubscription_Parser::DownloadableSubscription_Parser() 88 DownloadableSubscription_Parser::DownloadableSubscription_Parser()
89 : mFirstLine(true)
90 { 89 {
91 annotate_address(this, "DownloadableSubscription_Parser"); 90 annotate_address(this, "DownloadableSubscription_Parser");
92 } 91 }
93 92
94 namespace { 93 namespace {
95 const DependentString ADBLOCK_HEADER(u"[Adblock"_str); 94 const DependentString ADBLOCK_HEADER(u"[Adblock"_str);
95 const DependentString ADBLOCK_PLUS_EXTRA_HEADER(u"Plus"_str);
96
97 const DependentString ERROR_INVALID_DATA(u"synchronize_invalid_data"_str);
96 98
97 // Only check for trailing base64 padding. There should be at most 2 '='. 99 // Only check for trailing base64 padding. There should be at most 2 '='.
98 // In that case return a truncated string. 100 // In that case return a truncated string.
99 DependentString CleanUpChecksum(const String& checksum) 101 DependentString CleanUpChecksum(const String& checksum)
100 { 102 {
101 const auto len = checksum.length(); 103 const auto len = checksum.length();
102 if ((len > 22 && len <= 24) && 104 if ((len > 22 && len <= 24) &&
103 (checksum[22] == u'=' && (len == 23 || checksum[23] == u'='))) 105 (checksum[22] == u'=' && (len == 23 || checksum[23] == u'=')))
104 return DependentString(checksum, 0, 22); 106 return DependentString(checksum, 0, 22);
105 return DependentString(checksum); 107 return DependentString(checksum);
106 } 108 }
107 } 109 }
108 110
109 void DownloadableSubscription_Parser::Process(const String& line) 111 /// Return true if more line expected.
112 bool DownloadableSubscription_Parser::GetNextLine(DependentString& buffer, Depen dentString& line)
110 { 113 {
111 bool isHeader = false; 114 StringScanner scanner(buffer);
112 isHeader = line.find(ADBLOCK_HEADER) != String::npos; 115 String::value_type ch = 0;
113 if (!isHeader) 116 while (ch != u'\r' && ch != u'\n')
114 { 117 {
115 auto param = ParseParam(line); 118 ch = scanner.next();
116 if (param.first.is_invalid()) 119 if (ch == 0)
117 mFiltersText.emplace_back(line); 120 break;
118 else if (param.first == u"checksum"_str) 121 }
122
123 auto eol = scanner.position();
124 line.reset(buffer, 0, eol);
125 if (eol == 0 || ch == 0)
126 return false;
127 while (scanner.skipOne(u'\r') || scanner.skipOne(u'\n'))
128 ;
129 buffer.reset(buffer, scanner.position() + 1);
130 return true;
131 }
132
133 bool DownloadableSubscription_Parser::Process(const String& buffer)
134 {
135 DependentString currentBuffer(buffer);
136 bool firstLine = true;
137
138 DependentString line;
139 while (true)
140 {
141 bool more = GetNextLine(currentBuffer, line);
142 if (firstLine)
119 { 143 {
120 mParams[param.first] = CleanUpChecksum(param.second); 144 if (!ProcessFirstLine(line))
121 return; 145 {
146 mError = ERROR_INVALID_DATA;
147 return false;
148 }
149 firstLine = false;
122 } 150 }
123 else 151 else
124 mParams[param.first] = param.second; 152 ProcessLine(line);
153 if (!more)
154 break;
125 } 155 }
156 return true;
157 }
158
159 bool DownloadableSubscription_Parser::ProcessFirstLine(const String& line)
160 {
161 auto index = line.find(ADBLOCK_HEADER);
162 if (index == String::npos)
163 return false;
164
165 DependentString minVersion;
166 DependentString current(line, index + ADBLOCK_HEADER.length());
167 StringScanner scanner(current);
168 if (scanner.skipWhiteSpace() && scanner.skipString(ADBLOCK_PLUS_EXTRA_HEADER))
169 scanner.skipWhiteSpace();
170 index = scanner.position() + 1;
171 String::value_type ch = u'\0';
172 while((ch = scanner.next()) && (ch == u'.' || std::iswdigit(ch)))
173 ;
174 if (ch)
175 scanner.back();
176 if (scanner.position() + 1 > index)
177 minVersion.reset(current, index, scanner.position() + 1 - index);
178
179 if (ch != u']')
180 return false;
181
182 mRequiredVersion = minVersion;
183 mChecksum.Update(line);
184 return true;
185 }
186
187 void DownloadableSubscription_Parser::ProcessLine(const String& line)
188 {
189 auto param = ParseParam(line);
190 if (param.first.is_invalid())
191 {
192 if (!line.empty())
193 mFiltersText.emplace_back(line);
194 }
195 else if (param.first == u"checksum"_str)
196 {
197 mParams[param.first] = CleanUpChecksum(param.second);
198 return;
199 }
200 else
201 mParams[param.first] = param.second;
202
126 // Checksum is an MD5 checksum (base64-encoded without the trailing "=") of 203 // Checksum is an MD5 checksum (base64-encoded without the trailing "=") of
127 // all lines in UTF-8 without the checksum line, joined with "\n". 204 // all lines in UTF-8 without the checksum line, joined with "\n".
128 if (!mFirstLine) 205 mChecksum.Update((const uint8_t*)"\n", 1);
129 mChecksum.Update((const uint8_t*)"\n", 1);
130 else
131 mFirstLine = false;
132 mChecksum.Update(line); 206 mChecksum.Update(line);
133 } 207 }
134 208
135 int64_t DownloadableSubscription_Parser::ParseExpires(const String& expires) 209 int64_t DownloadableSubscription_Parser::ParseExpires(const String& expires)
136 { 210 {
137 bool isHour = false; 211 bool isHour = false;
138 StringScanner scanner(expires); 212 StringScanner scanner(expires);
139 String::size_type numStart = 0; 213 String::size_type numStart = 0;
140 String::size_type numLen = 0; 214 String::size_type numLen = 0;
141 while(!scanner.done()) 215 while(!scanner.done())
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 mB64Checksum = ToBase64(checksum, MD5::CHECKSUM_LENGTH); 271 mB64Checksum = ToBase64(checksum, MD5::CHECKSUM_LENGTH);
198 } 272 }
199 return (mParams[u"checksum"_str] == mB64Checksum); 273 return (mParams[u"checksum"_str] == mB64Checksum);
200 } 274 }
201 275
202 int64_t DownloadableSubscription_Parser::Finalize(DownloadableSubscription& subs cription) 276 int64_t DownloadableSubscription_Parser::Finalize(DownloadableSubscription& subs cription)
203 { 277 {
204 if (mB64Checksum.is_invalid()) 278 if (mB64Checksum.is_invalid())
205 VerifyChecksum(); // here we ignore the checksum, but we calculate it. 279 VerifyChecksum(); // here we ignore the checksum, but we calculate it.
206 280
281 FilterNotifier::SubscriptionChange(
282 FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED,
283 subscription);
284
285 if (!mRequiredVersion.empty())
286 subscription.SetRequiredVersion(mRequiredVersion);
287
207 auto entry = mParams.find(u"title"_str); 288 auto entry = mParams.find(u"title"_str);
208 if (entry) 289 if (entry)
209 { 290 {
210 subscription.SetTitle(entry->second); 291 subscription.SetTitle(entry->second);
211 subscription.SetFixedTitle(true); 292 subscription.SetFixedTitle(true);
212 } 293 }
213 else 294 else
214 subscription.SetFixedTitle(false); 295 subscription.SetFixedTitle(false);
215 296
216 int32_t version = 0; 297 int32_t version = 0;
217 entry = mParams.find(u"version"_str); 298 entry = mParams.find(u"version"_str);
218 if (entry) 299 if (entry)
219 version = entry->second.toInt<int32_t>(); 300 version = entry->second.toInt<int32_t>();
220 subscription.SetDataRevision(version); 301 subscription.SetDataRevision(version);
221 302
222 int64_t expires = 0; 303 int64_t expires = 0;
223 entry = mParams.find(u"expires"_str); 304 entry = mParams.find(u"expires"_str);
224 if (entry) 305 if (entry)
225 expires = ParseExpires(entry->second); 306 expires = ParseExpires(entry->second);
226 307
227 FilterNotifier::SubscriptionChange(
228 FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED,
229 subscription);
230
231 Subscription::Filters filters; 308 Subscription::Filters filters;
232 filters.reserve(mFiltersText.size()); 309 filters.reserve(mFiltersText.size());
233 for (auto text : mFiltersText) 310 for (auto text : mFiltersText)
234 { 311 {
235 DependentString dependent(text); 312 DependentString dependent(text);
236 filters.emplace_back(Filter::FromText(dependent), false); 313 filters.emplace_back(Filter::FromText(dependent), false);
237 } 314 }
238 315
239 subscription.SetFilters(std::move(filters)); 316 subscription.SetFilters(std::move(filters));
240 FilterNotifier::SubscriptionChange( 317 FilterNotifier::SubscriptionChange(
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 result.append(u'\n'); 419 result.append(u'\n');
343 } 420 }
344 if (mDownloadCount) 421 if (mDownloadCount)
345 { 422 {
346 result.append(u"downloadCount="_str); 423 result.append(u"downloadCount="_str);
347 result.append(mDownloadCount); 424 result.append(mDownloadCount);
348 result.append(u'\n'); 425 result.append(u'\n');
349 } 426 }
350 return result; 427 return result;
351 } 428 }
OLDNEW
« no previous file with comments | « compiled/subscription/DownloadableSubscription.h ('k') | lib/synchronizer.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld