Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: sdk/lib/io/http_headers.dart

Issue 124753002: Code cleanup (mostly io lib and some http lib). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 part of dart.io; 5 part of dart.io;
6 6
7 class _HttpHeaders implements HttpHeaders { 7 class _HttpHeaders implements HttpHeaders {
8 final Map<String, List<String>> _headers; 8 final Map<String, List<String>> _headers;
9 final String protocolVersion; 9 final String protocolVersion;
10 10
11 bool _mutable = true; // Are the headers currently mutable? 11 bool _mutable = true; // Are the headers currently mutable?
12 List<String> _noFoldingHeaders; 12 List<String> _noFoldingHeaders;
13 13
14 int _contentLength = -1; 14 int _contentLength = -1;
15 bool _persistentConnection = true; 15 bool _persistentConnection = true;
16 bool _chunkedTransferEncoding = false; 16 bool _chunkedTransferEncoding = false;
17 String _host; 17 String _host;
18 int _port; 18 int _port;
19 19
20 _HttpHeaders(String this.protocolVersion) 20 _HttpHeaders(this.protocolVersion)
21 : _headers = new HashMap<String, List<String>>() { 21 : _headers = new HashMap<String, List<String>>() {
22 if (protocolVersion == "1.0") { 22 if (protocolVersion == "1.0") {
23 _persistentConnection = false; 23 _persistentConnection = false;
24 } 24 }
25 } 25 }
26 26
27 List<String> operator[](String name) { 27 List<String> operator[](String name) => _headers[name.toLowerCase()];
28 name = name.toLowerCase();
29 return _headers[name];
30 }
31 28
32 String value(String name) { 29 String value(String name) {
33 name = name.toLowerCase(); 30 name = name.toLowerCase();
34 List<String> values = _headers[name]; 31 List<String> values = _headers[name];
35 if (values == null) return null; 32 if (values == null) return null;
36 if (values.length > 1) { 33 if (values.length > 1) {
37 throw new HttpException("More than one value for header $name"); 34 throw new HttpException("More than one value for header $name");
38 } 35 }
39 return values[0]; 36 return values[0];
40 } 37 }
41 38
42 void add(String name, value) { 39 void add(String name, value) {
43 _checkMutable(); 40 _checkMutable();
44 _addAll(name.toLowerCase(), value); 41 _addAll(name.toLowerCase(), value);
45 } 42 }
46 43
47 void _addAll(String name, value) { 44 void _addAll(String name, value) {
48 if (value is List) { 45 if (value is List) {
49 for (int i = 0; i < value.length; i++) { 46 value.forEach((v) => _add(name, v));
Lasse Reichstein Nielsen 2014/01/06 09:29:30 This may be a little slower than the original. Pro
50 _add(name, value[i]);
51 }
52 } else { 47 } else {
53 _add(name, value); 48 _add(name, value);
54 } 49 }
55 } 50 }
56 51
57 void set(String name, Object value) { 52 void set(String name, Object value) {
58 _checkMutable(); 53 _checkMutable();
59 name = name.toLowerCase(); 54 name = name.toLowerCase();
60 _headers.remove(name); 55 _headers.remove(name);
61 _addAll(name, value); 56 _addAll(name, value);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } 240 }
246 241
247 void set contentType(ContentType contentType) { 242 void set contentType(ContentType contentType) {
248 _checkMutable(); 243 _checkMutable();
249 _set(HttpHeaders.CONTENT_TYPE, contentType.toString()); 244 _set(HttpHeaders.CONTENT_TYPE, contentType.toString());
250 } 245 }
251 246
252 // [name] must be a lower-case version of the name. 247 // [name] must be a lower-case version of the name.
253 void _add(String name, value) { 248 void _add(String name, value) {
254 // TODO(sgjesse): Add immutable state throw HttpException is immutable. 249 // TODO(sgjesse): Add immutable state throw HttpException is immutable.
255 if (name == HttpHeaders.CONTENT_LENGTH) { 250 switch (name) {
256 if (value is int) { 251 case HttpHeaders.CONTENT_LENGTH:
257 contentLength = value; 252 if (value is int) {
258 } else if (value is String) { 253 contentLength = value;
259 contentLength = int.parse(value); 254 } else if (value is String) {
260 } else { 255 contentLength = int.parse(value);
261 throw new HttpException("Unexpected type for header named $name");
262 }
263 } else if (name == HttpHeaders.TRANSFER_ENCODING) {
264 if (value == "chunked") {
265 chunkedTransferEncoding = true;
266 } else {
267 _addValue(name, value);
268 }
269 } else if (name == HttpHeaders.DATE) {
270 if (value is DateTime) {
271 date = value;
272 } else if (value is String) {
273 _set(HttpHeaders.DATE, value);
274 } else {
275 throw new HttpException("Unexpected type for header named $name");
276 }
277 } else if (name == HttpHeaders.EXPIRES) {
278 if (value is DateTime) {
279 expires = value;
280 } else if (value is String) {
281 _set(HttpHeaders.EXPIRES, value);
282 } else {
283 throw new HttpException("Unexpected type for header named $name");
284 }
285 } else if (name == HttpHeaders.IF_MODIFIED_SINCE) {
286 if (value is DateTime) {
287 ifModifiedSince = value;
288 } else if (value is String) {
289 _set(HttpHeaders.IF_MODIFIED_SINCE, value);
290 } else {
291 throw new HttpException("Unexpected type for header named $name");
292 }
293 } else if (name == HttpHeaders.HOST) {
294 if (value is String) {
295 int pos = value.indexOf(":");
296 if (pos == -1) {
297 _host = value;
298 _port = HttpClient.DEFAULT_HTTP_PORT;
299 } else { 256 } else {
300 if (pos > 0) { 257 throw new HttpException("Unexpected type for header named $name");
301 _host = value.substring(0, pos); 258 }
302 } else { 259 break;
303 _host = null; 260
304 } 261 case HttpHeaders.TRANSFER_ENCODING:
305 if (pos + 1 == value.length) { 262 if (value == "chunked") {
263 chunkedTransferEncoding = true;
264 } else {
265 _addValue(name, value);
266 }
267 break;
268
269 case HttpHeaders.DATE:
270 if (value is DateTime) {
271 date = value;
272 } else if (value is String) {
273 _set(HttpHeaders.DATE, value);
274 } else {
275 throw new HttpException("Unexpected type for header named $name");
276 }
277 break;
278
279 case HttpHeaders.EXPIRES:
280 if (value is DateTime) {
281 expires = value;
282 } else if (value is String) {
283 _set(HttpHeaders.EXPIRES, value);
284 } else {
285 throw new HttpException("Unexpected type for header named $name");
286 }
287 break;
288
289 case HttpHeaders.IF_MODIFIED_SINCE:
290 if (value is DateTime) {
291 ifModifiedSince = value;
292 } else if (value is String) {
293 _set(HttpHeaders.IF_MODIFIED_SINCE, value);
294 } else {
295 throw new HttpException("Unexpected type for header named $name");
296 }
297 break;
298
299 case HttpHeaders.HOST:
300 if (value is String) {
301 int pos = value.indexOf(":");
302 if (pos == -1) {
303 _host = value;
306 _port = HttpClient.DEFAULT_HTTP_PORT; 304 _port = HttpClient.DEFAULT_HTTP_PORT;
307 } else { 305 } else {
308 try { 306 if (pos > 0) {
309 _port = int.parse(value.substring(pos + 1)); 307 _host = value.substring(0, pos);
310 } on FormatException catch (e) { 308 } else {
311 _port = null; 309 _host = null;
310 }
311 if (pos + 1 == value.length) {
312 _port = HttpClient.DEFAULT_HTTP_PORT;
313 } else {
314 try {
315 _port = int.parse(value.substring(pos + 1));
316 } on FormatException catch (e) {
317 _port = null;
318 }
312 } 319 }
313 } 320 }
321 _set(HttpHeaders.HOST, value);
322 } else {
323 throw new HttpException("Unexpected type for header named $name");
314 } 324 }
315 _set(HttpHeaders.HOST, value); 325 break;
316 } else { 326
317 throw new HttpException("Unexpected type for header named $name"); 327 case HttpHeaders.CONNECTION:
318 } 328 var lowerCaseValue = value.toLowerCase();
319 } else if (name == HttpHeaders.CONNECTION) { 329 if (lowerCaseValue == 'close') {
320 var lowerCaseValue = value.toLowerCase(); 330 _persistentConnection = false;
321 if (lowerCaseValue == 'close') { 331 } else if (lowerCaseValue == 'keep-alive') {
322 _persistentConnection = false; 332 _persistentConnection = true;
323 } else if (lowerCaseValue == 'keep-alive') { 333 }
324 _persistentConnection = true; 334 _addValue(name, value);
325 } 335 break;
326 _addValue(name, value); 336
327 } else if (name == HttpHeaders.CONTENT_TYPE) { 337 case HttpHeaders.CONTENT_TYPE:
328 _set(HttpHeaders.CONTENT_TYPE, value); 338 _set(HttpHeaders.CONTENT_TYPE, value);
329 } else { 339 break;
330 _addValue(name, value); 340
341 default:
342 _addValue(name, value);
331 } 343 }
332 } 344 }
333 345
334 void _addValue(String name, Object value) { 346 void _addValue(String name, Object value) {
335 List<String> values = _headers[name]; 347 List<String> values = _headers[name];
336 if (values == null) { 348 if (values == null) {
337 values = new List<String>(); 349 values = new List<String>();
338 _headers[name] = values; 350 _headers[name] = values;
339 } 351 }
340 if (value is DateTime) { 352 if (value is DateTime) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 write(values[i].codeUnits); 414 write(values[i].codeUnits);
403 } 415 }
404 write(const [_CharCode.CR, _CharCode.LF]); 416 write(const [_CharCode.CR, _CharCode.LF]);
405 }); 417 });
406 return offset; 418 return offset;
407 } 419 }
408 420
409 String toString() { 421 String toString() {
410 StringBuffer sb = new StringBuffer(); 422 StringBuffer sb = new StringBuffer();
411 _headers.forEach((String name, List<String> values) { 423 _headers.forEach((String name, List<String> values) {
412 sb.write(name); 424 sb..write(name)
413 sb.write(": "); 425 ..write(": ");
Lasse Reichstein Nielsen 2014/01/06 09:29:30 Hmm, technically the second line should be indente
414 bool fold = _foldHeader(name); 426 bool fold = _foldHeader(name);
415 for (int i = 0; i < values.length; i++) { 427 for (int i = 0; i < values.length; i++) {
416 if (i > 0) { 428 if (i > 0) {
417 if (fold) { 429 if (fold) {
418 sb.write(", "); 430 sb.write(", ");
419 } else { 431 } else {
420 sb.write("\n"); 432 sb..write("\n")
421 sb.write(name); 433 ..write(name)
422 sb.write(": "); 434 ..write(": ");
423 } 435 }
424 } 436 }
425 sb.write(values[i]); 437 sb.write(values[i]);
426 } 438 }
427 sb.write("\n"); 439 sb.write("\n");
428 }); 440 });
429 return sb.toString(); 441 return sb.toString();
430 } 442 }
431 443
432 List<Cookie> _parseCookies() { 444 List<Cookie> _parseCookies() {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 Map<String, String> get parameters { 538 Map<String, String> get parameters {
527 _ensureParameters(); 539 _ensureParameters();
528 return _parameters; 540 return _parameters;
529 } 541 }
530 542
531 String toString() { 543 String toString() {
532 StringBuffer sb = new StringBuffer(); 544 StringBuffer sb = new StringBuffer();
533 sb.write(_value); 545 sb.write(_value);
534 if (parameters != null && parameters.length > 0) { 546 if (parameters != null && parameters.length > 0) {
535 _parameters.forEach((String name, String value) { 547 _parameters.forEach((String name, String value) {
536 sb.write("; "); 548 sb..write("; ")
537 sb.write(name); 549 ..write(name)
538 sb.write("="); 550 ..write("=")
539 sb.write(value); 551 ..write(value);
540 }); 552 });
541 } 553 }
542 return sb.toString(); 554 return sb.toString();
543 } 555 }
544 556
545 void _parse(String s, String parameterSeparator, bool preserveBackslash) { 557 void _parse(String s, String parameterSeparator, bool preserveBackslash) {
546 int index = 0; 558 int index = 0;
547 559
548 bool done() => index == s.length; 560 bool done() => index == s.length;
549 561
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 699
688 String get primaryType => _primaryType; 700 String get primaryType => _primaryType;
689 701
690 String get subType => _subType; 702 String get subType => _subType;
691 703
692 String get charset => parameters["charset"]; 704 String get charset => parameters["charset"];
693 } 705 }
694 706
695 707
696 class _Cookie implements Cookie { 708 class _Cookie implements Cookie {
697 _Cookie([String this.name, String this.value]); 709 String name;
Lasse Reichstein Nielsen 2014/01/06 09:29:30 Are none of these really final?
710 String value;
711 DateTime expires;
712 int maxAge;
713 String domain;
714 String path;
715 bool httpOnly = false;
716 bool secure = false;
717
718 _Cookie([this.name, this.value]);
698 719
699 _Cookie.fromSetCookieValue(String value) { 720 _Cookie.fromSetCookieValue(String value) {
700 // Parse the 'set-cookie' header value. 721 // Parse the 'set-cookie' header value.
701 _parseSetCookieValue(value); 722 _parseSetCookieValue(value);
702 } 723 }
703 724
704 // Parse a 'set-cookie' header value according to the rules in RFC 6265. 725 // Parse a 'set-cookie' header value according to the rules in RFC 6265.
705 void _parseSetCookieValue(String s) { 726 void _parseSetCookieValue(String s) {
706 int index = 0; 727 int index = 0;
707 728
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 803 }
783 index++; // Skip the = character. 804 index++; // Skip the = character.
784 value = parseValue(); 805 value = parseValue();
785 if (done()) return; 806 if (done()) return;
786 index++; // Skip the ; character. 807 index++; // Skip the ; character.
787 parseAttributes(); 808 parseAttributes();
788 } 809 }
789 810
790 String toString() { 811 String toString() {
791 StringBuffer sb = new StringBuffer(); 812 StringBuffer sb = new StringBuffer();
792 sb.write(name); 813 sb..write(name)
793 sb.write("="); 814 ..write("=")
794 sb.write(value); 815 ..write(value);
795 if (expires != null) { 816 if (expires != null) {
796 sb.write("; Expires="); 817 sb..write("; Expires=")
797 sb.write(HttpDate.format(expires)); 818 ..write(HttpDate.format(expires));
798 } 819 }
799 if (maxAge != null) { 820 if (maxAge != null) {
800 sb.write("; Max-Age="); 821 sb..write("; Max-Age=")
801 sb.write(maxAge); 822 ..write(maxAge);
802 } 823 }
803 if (domain != null) { 824 if (domain != null) {
804 sb.write("; Domain="); 825 sb..write("; Domain=")
805 sb.write(domain); 826 ..write(domain);
806 } 827 }
807 if (path != null) { 828 if (path != null) {
808 sb.write("; Path="); 829 sb..write("; Path=")
809 sb.write(path); 830 ..write(path);
810 } 831 }
811 if (secure) sb.write("; Secure"); 832 if (secure) sb.write("; Secure");
812 if (httpOnly) sb.write("; HttpOnly"); 833 if (httpOnly) sb.write("; HttpOnly");
813 return sb.toString(); 834 return sb.toString();
814 } 835 }
815
816 String name;
817 String value;
818 DateTime expires;
819 int maxAge;
820 String domain;
821 String path;
822 bool httpOnly = false;
823 bool secure = false;
824 } 836 }
825 837
826 838
827 class _UnmodifiableMap<K, V> implements Map<K, V> { 839 class _UnmodifiableMap<K, V> implements Map<K, V> {
828 final Map _map; 840 final Map _map;
829 const _UnmodifiableMap(this._map); 841 const _UnmodifiableMap(this._map);
830 842
831 bool containsValue(Object value) => _map.containsValue(value); 843 bool containsValue(Object value) => _map.containsValue(value);
832 bool containsKey(Object key) => _map.containsKey(key); 844 bool containsKey(Object key) => _map.containsKey(key);
833 V operator [](Object key) => _map[key]; 845 V operator [](Object key) => _map[key];
(...skipping 12 matching lines...) Expand all
846 void clear() { 858 void clear() {
847 throw new UnsupportedError("Cannot modify an unmodifiable map"); 859 throw new UnsupportedError("Cannot modify an unmodifiable map");
848 } 860 }
849 void forEach(void f(K key, V value)) => _map.forEach(f); 861 void forEach(void f(K key, V value)) => _map.forEach(f);
850 Iterable<K> get keys => _map.keys; 862 Iterable<K> get keys => _map.keys;
851 Iterable<V> get values => _map.values; 863 Iterable<V> get values => _map.values;
852 int get length => _map.length; 864 int get length => _map.length;
853 bool get isEmpty => _map.isEmpty; 865 bool get isEmpty => _map.isEmpty;
854 bool get isNotEmpty => _map.isNotEmpty; 866 bool get isNotEmpty => _map.isNotEmpty;
855 } 867 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698