Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 class _HttpUtils { | 5 class _HttpUtils { |
| 6 static String decodeUrlEncodedString(String urlEncoded) { | 6 static String decodeUrlEncodedString(String urlEncoded) { |
| 7 // First check the string for any encoding. | 7 // First check the string for any encoding. |
| 8 int index = 0; | 8 int index = 0; |
| 9 bool encoded = false; | 9 bool encoded = false; |
| 10 while (!encoded && index < urlEncoded.length) { | 10 while (!encoded && index < urlEncoded.length) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 d.hour < 9 ? sb.add(" 0") : sb.add(" "); | 110 d.hour < 9 ? sb.add(" 0") : sb.add(" "); |
| 111 sb.add(d.hour.toString()); | 111 sb.add(d.hour.toString()); |
| 112 d.minute < 9 ? sb.add(":0") : sb.add(":"); | 112 d.minute < 9 ? sb.add(":0") : sb.add(":"); |
| 113 sb.add(d.minute.toString()); | 113 sb.add(d.minute.toString()); |
| 114 d.second < 9 ? sb.add(":0") : sb.add(":"); | 114 d.second < 9 ? sb.add(":0") : sb.add(":"); |
| 115 sb.add(d.second.toString()); | 115 sb.add(d.second.toString()); |
| 116 sb.add(" GMT"); | 116 sb.add(" GMT"); |
| 117 return sb.toString(); | 117 return sb.toString(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 static Date parseDate(String date, [bool strict = true]) { | 120 static Date parseDate(String date) { |
| 121 final int SP = 32; | 121 final int SP = 32; |
| 122 List wkdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; | 122 List wkdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; |
| 123 List weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", | 123 List weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", |
| 124 "Friday", "Saturday", "Sunday"]; | 124 "Friday", "Saturday", "Sunday"]; |
| 125 List months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", | 125 List months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", |
| 126 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | 126 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; |
| 127 List wkdaysLowerCase = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; | 127 List wkdaysLowerCase = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; |
| 128 List weekdaysLowerCase = ["monday", "tuesday", "wednesday", "thursday", | 128 List weekdaysLowerCase = ["monday", "tuesday", "wednesday", "thursday", |
| 129 "friday", "saturday", "sunday"]; | 129 "friday", "saturday", "sunday"]; |
| 130 List monthsLowerCase = ["jan", "feb", "mar", "apr", "may", "jun", | 130 List monthsLowerCase = ["jan", "feb", "mar", "apr", "may", "jun", |
| 131 "jul", "aug", "sep", "oct", "nov", "dec"]; | 131 "jul", "aug", "sep", "oct", "nov", "dec"]; |
| 132 | 132 |
| 133 final int formatRfc1123 = 0; | 133 final int formatRfc1123 = 0; |
| 134 final int formatRfc850 = 1; | 134 final int formatRfc850 = 1; |
| 135 final int formatAsctime = 2; | 135 final int formatAsctime = 2; |
| 136 | 136 |
| 137 int index = 0; | 137 int index = 0; |
| 138 String tmp; | 138 String tmp; |
| 139 int format; | 139 int format; |
| 140 | 140 |
| 141 void expect(String s) { | 141 void expect(String s) { |
| 142 if (date.length - index < s.length) { | 142 if (date.length - index < s.length) { |
| 143 throw new HttpException("Invalid HTTP date $date"); | 143 throw new HttpException("Invalid HTTP date $date"); |
| 144 } | 144 } |
| 145 String tmp = date.substring(index, index + s.length); | 145 String tmp = date.substring(index, index + s.length); |
| 146 if (strict) { | 146 if (tmp != s) { |
| 147 if (tmp != s) { | 147 throw new HttpException("Invalid HTTP date $date"); |
| 148 throw new HttpException("Invalid HTTP date $date"); | |
| 149 } | |
| 150 } else { | |
| 151 if (tmp.toLowerCase() != s.toLowerCase()) { | |
| 152 throw new HttpException("Invalid HTTP date $date"); | |
| 153 } | |
| 154 } | 148 } |
| 155 index += s.length; | 149 index += s.length; |
| 156 } | 150 } |
| 157 | 151 |
| 158 int expectWeekday() { | 152 int expectWeekday() { |
| 159 int weekday; | 153 int weekday; |
| 160 // The formatting of the weekday signals the format of the date string. | 154 // The formatting of the weekday signals the format of the date string. |
| 161 int pos = date.indexOf(",", index); | 155 int pos = date.indexOf(",", index); |
| 162 if (pos == -1) { | 156 if (pos == -1) { |
| 163 int pos = date.indexOf(" ", index); | 157 int pos = date.indexOf(" ", index); |
| 164 if (pos == -1) throw new HttpException("Invalid HTTP date $date"); | 158 if (pos == -1) throw new HttpException("Invalid HTTP date $date"); |
| 165 tmp = date.substring(index, pos); | 159 tmp = date.substring(index, pos); |
| 166 index = pos + 1; | 160 index = pos + 1; |
| 167 weekday = strict ? wkdays.indexOf(tmp) | 161 weekday = wkdays.indexOf(tmp); |
| 168 : wkdaysLowerCase.indexOf(tmp.toLowerCase()); | |
| 169 if (weekday != -1) { | 162 if (weekday != -1) { |
| 170 format = formatAsctime; | 163 format = formatAsctime; |
| 171 return weekday; | 164 return weekday; |
| 172 } | 165 } |
| 173 } else { | 166 } else { |
| 174 tmp = date.substring(index, pos); | 167 tmp = date.substring(index, pos); |
| 175 index = pos + 1; | 168 index = pos + 1; |
| 176 weekday = strict ? wkdays.indexOf(tmp) | 169 weekday = wkdays.indexOf(tmp); |
| 177 : wkdaysLowerCase.indexOf(tmp.toLowerCase()); | |
| 178 if (weekday != -1) { | 170 if (weekday != -1) { |
| 179 format = formatRfc1123; | 171 format = formatRfc1123; |
| 180 return weekday; | 172 return weekday; |
| 181 } | 173 } |
| 182 weekday = strict ? weekdays.indexOf(tmp) | 174 weekday = weekdays.indexOf(tmp); |
| 183 : weekdaysLowerCase.indexOf(tmp.toLowerCase()); | |
| 184 if (weekday != -1) { | 175 if (weekday != -1) { |
| 185 format = formatRfc850; | 176 format = formatRfc850; |
| 186 return weekday; | 177 return weekday; |
| 187 } | 178 } |
| 188 } | 179 } |
| 189 throw new HttpException("Invalid HTTP date $date"); | 180 throw new HttpException("Invalid HTTP date $date"); |
| 190 } | 181 } |
| 191 | 182 |
| 192 int expectMonth(String separator) { | 183 int expectMonth(String separator) { |
| 193 int pos = date.indexOf(separator, index); | 184 int pos = date.indexOf(separator, index); |
| 194 if (pos - index != 3) throw new HttpException("Invalid HTTP date $date"); | 185 if (pos - index != 3) throw new HttpException("Invalid HTTP date $date"); |
| 195 tmp = date.substring(index, pos); | 186 tmp = date.substring(index, pos); |
| 196 index = pos + 1; | 187 index = pos + 1; |
| 197 int month = strict ? months.indexOf(tmp) | 188 int month = months.indexOf(tmp); |
| 198 : monthsLowerCase.indexOf(tmp.toLowerCase()); | |
| 199 if (month != -1) return month; | 189 if (month != -1) return month; |
| 200 throw new HttpException("Invalid HTTP date $date"); | 190 throw new HttpException("Invalid HTTP date $date"); |
| 201 } | 191 } |
| 202 | 192 |
| 203 int expectNum(String separator) { | 193 int expectNum(String separator) { |
| 204 int pos; | 194 int pos; |
| 205 if (separator.length > 0) { | 195 if (separator.length > 0) { |
| 206 pos = date.indexOf(separator, index); | 196 pos = date.indexOf(separator, index); |
| 207 } else { | 197 } else { |
| 208 pos = date.length; | 198 pos = date.length; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 year = expectNum(" "); | 235 year = expectNum(" "); |
| 246 hours = expectNum(":"); | 236 hours = expectNum(":"); |
| 247 minutes = expectNum(":"); | 237 minutes = expectNum(":"); |
| 248 seconds = expectNum(" "); | 238 seconds = expectNum(" "); |
| 249 expect("GMT"); | 239 expect("GMT"); |
| 250 } | 240 } |
| 251 expectEnd(); | 241 expectEnd(); |
| 252 return new Date( | 242 return new Date( |
| 253 year, month + 1, day, hours, minutes, seconds, 0, isUtc: true); | 243 year, month + 1, day, hours, minutes, seconds, 0, isUtc: true); |
| 254 } | 244 } |
| 245 | |
| 246 static Date parseCookieDate(String date) { | |
| 247 List monthsLowerCase = ["jan", "feb", "mar", "apr", "may", "jun", | |
| 248 "jul", "aug", "sep", "oct", "nov", "dec"]; | |
| 249 | |
| 250 int position = 0; | |
| 251 | |
| 252 void error() { | |
| 253 throw new HttpException("Invalid HTTP date $date"); | |
|
Søren Gjesse
2012/09/04 06:51:57
HTTP -> cookie
Anders Johnsen
2012/09/04 07:03:13
Done.
| |
| 254 } | |
| 255 | |
| 256 bool isEnd() { | |
| 257 return position >= date.length; | |
|
Søren Gjesse
2012/09/04 06:51:57
Shouldn't this be just ==?
Anders Johnsen
2012/09/04 07:03:13
In theory, yes. I'll change. If we crash without i
| |
| 258 } | |
| 259 | |
| 260 bool isDelimiter(String s) { | |
|
Søren Gjesse
2012/09/04 06:51:57
How about passing the index here and use s.charCod
Anders Johnsen
2012/09/04 07:03:13
Keeping, as discussed off-list.
| |
| 261 int char = s.charCodeAt(0); | |
| 262 if (char === 0x09) return true; | |
| 263 if (char >= 0x20 && char <= 0x2F) return true; | |
| 264 if (char >= 0x3B && char <= 0x40) return true; | |
| 265 if (char >= 0x5B && char <= 0x60) return true; | |
| 266 if (char >= 0x7B && char <= 0x7E) return true; | |
| 267 return false; | |
| 268 } | |
| 269 | |
| 270 bool isNonDelimiter(String s) { | |
| 271 int char = s.charCodeAt(0); | |
| 272 if (char >= 0x00 && char <= 0x08) return true; | |
| 273 if (char >= 0x0A && char <= 0x1F) return true; | |
| 274 if (char >= 0x30 && char <= 0x39) return true; // Digit | |
| 275 if (char == 0x3A) return true; // ':' | |
| 276 if (char >= 0x41 && char <= 0x5A) return true; // Alpha | |
| 277 if (char >= 0x61 && char <= 0x7A) return true; // Alpha | |
| 278 if (char >= 0x7F && char <= 0xFF) return true; // Alpha | |
| 279 return false; | |
| 280 } | |
| 281 | |
| 282 bool isDigit(String s) { | |
| 283 int char = s.charCodeAt(0); | |
| 284 if (char > 0x2F && char < 0x3A) return true; | |
| 285 return false; | |
| 286 } | |
| 287 | |
| 288 int getMonth(String month) { | |
| 289 if (month.length < 3) return -1; | |
| 290 return monthsLowerCase.indexOf(month.substring(0, 3)); | |
| 291 } | |
| 292 | |
| 293 int toInt(String s) { | |
| 294 int index = 0; | |
| 295 for (; index < s.length && isDigit(s[index]); index++); | |
| 296 return parseInt(s.substring(0, index)); | |
| 297 } | |
| 298 | |
| 299 var tokens = []; | |
| 300 while (!isEnd()) { | |
| 301 while (!isEnd() && isDelimiter(date[position])) position++; | |
| 302 | |
| 303 var word = ""; | |
| 304 while (!isEnd() && isNonDelimiter(date[position])) { | |
|
Søren Gjesse
2012/09/04 06:51:57
How about saving position before the loop, just in
Anders Johnsen
2012/09/04 07:03:13
Done.
| |
| 305 word = "$word${date[position++]}"; | |
| 306 } | |
| 307 while (!isEnd() && isDelimiter(date[position])) position++; | |
| 308 tokens.add(word.toLowerCase()); | |
| 309 } | |
| 310 | |
| 311 String timeStr; | |
| 312 String dayOfMonthStr; | |
| 313 String monthStr; | |
| 314 String yearStr; | |
| 315 | |
| 316 for (var token in tokens) { | |
| 317 if (token.length < 1) return null; | |
|
Søren Gjesse
2012/09/04 06:51:57
Shouldn't this be a continue instead of return nul
Anders Johnsen
2012/09/04 07:03:13
That is a very good point! Changed.
| |
| 318 if (timeStr === null && token.length >= 5 && isDigit(token[0]) && | |
| 319 (token[1] == ":" || (isDigit(token[1]) && token[2] == ":"))) { | |
| 320 timeStr = token; | |
| 321 } else if (dayOfMonthStr === null && isDigit(token[0])) { | |
| 322 dayOfMonthStr = token; | |
| 323 } else if (monthStr === null && getMonth(token) >= 0) { | |
| 324 monthStr = token; | |
| 325 } else if (yearStr === null && token.length >= 2 && | |
| 326 isDigit(token[0]) && isDigit(token[1])) { | |
| 327 yearStr = token; | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 if (timeStr === null || dayOfMonthStr === null || | |
| 332 monthStr === null || yearStr === null) error(); | |
| 333 | |
| 334 int year = toInt(yearStr); | |
| 335 if (year >= 70 && year <= 99) year += 1900; | |
| 336 else if (year >= 0 && year <= 69) year += 2000; | |
| 337 if (year < 1601) error(); | |
| 338 | |
| 339 int dayOfMonth = toInt(dayOfMonthStr); | |
| 340 if (dayOfMonth < 1 || dayOfMonth > 31) error(); | |
| 341 | |
| 342 int month = getMonth(monthStr) + 1; | |
| 343 | |
| 344 var timeList = timeStr.split(":"); | |
| 345 if (timeList.length !== 3) error(); | |
| 346 int hour = toInt(timeList[0]); | |
| 347 int minute = toInt(timeList[1]); | |
| 348 int second = toInt(timeList[2]); | |
| 349 if (hour > 23) error(); | |
| 350 if (minute > 59) error(); | |
| 351 if (second > 59) error(); | |
| 352 | |
| 353 return new Date(year, month, dayOfMonth, hour, minute, second, 0, true); | |
| 354 } | |
| 255 } | 355 } |
| OLD | NEW |