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

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

Issue 12316036: Merge IO v2 branch to bleeding edge (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased to r18818 Created 7 years, 10 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
« no previous file with comments | « sdk/lib/io/http.dart ('k') | sdk/lib/io/http_impl.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart.io; 5 part of dart.io;
6 6
7 class _HttpHeaders implements HttpHeaders { 7 class _HttpHeaders implements HttpHeaders {
8 _HttpHeaders() : _headers = new Map<String, List<String>>(); 8 _HttpHeaders(String this.protocolVersion)
9 : _headers = new Map<String, List<String>>();
9 10
10 List<String> operator[](String name) { 11 List<String> operator[](String name) {
11 name = name.toLowerCase(); 12 name = name.toLowerCase();
12 return _headers[name]; 13 return _headers[name];
13 } 14 }
14 15
15 String value(String name) { 16 String value(String name) {
16 name = name.toLowerCase(); 17 name = name.toLowerCase();
17 List<String> values = _headers[name]; 18 List<String> values = _headers[name];
18 if (values == null) return null; 19 if (values == null) return null;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 61
61 void forEach(void f(String name, List<String> values)) { 62 void forEach(void f(String name, List<String> values)) {
62 _headers.forEach(f); 63 _headers.forEach(f);
63 } 64 }
64 65
65 void noFolding(String name) { 66 void noFolding(String name) {
66 if (_noFoldingHeaders == null) _noFoldingHeaders = new List<String>(); 67 if (_noFoldingHeaders == null) _noFoldingHeaders = new List<String>();
67 _noFoldingHeaders.add(name); 68 _noFoldingHeaders.add(name);
68 } 69 }
69 70
71 bool get persistentConnection {
72 List<String> connection = this[HttpHeaders.CONNECTION];
73 if (protocolVersion == "1.1") {
74 if (connection == null) return true;
75 return !connection.any((value) => value.toLowerCase() == "close");
76 } else {
77 if (connection == null) return false;
78 return connection.any((value) => value.toLowerCase() == "keep-alive");
79 }
80 }
81
82 void set persistentConnection(bool persistentConnection) {
83 _checkMutable();
84 // Determine the value of the "Connection" header.
85 remove(HttpHeaders.CONNECTION, "close");
86 remove(HttpHeaders.CONNECTION, "keep-alive");
87 if (protocolVersion == "1.1" && !persistentConnection) {
88 add(HttpHeaders.CONNECTION, "close");
89 } else if (protocolVersion == "1.0" && persistentConnection) {
90 add(HttpHeaders.CONNECTION, "keep-alive");
91 }
92 }
93
70 int get contentLength => _contentLength; 94 int get contentLength => _contentLength;
71 95
72 void set contentLength(int contentLength) { 96 void set contentLength(int contentLength) {
73 _checkMutable(); 97 _checkMutable();
74 _contentLength = contentLength; 98 _contentLength = contentLength;
75 if (_contentLength >= 0) { 99 if (_contentLength >= 0) {
76 _set("content-length", contentLength.toString()); 100 _set("content-length", contentLength.toString());
77 } else { 101 } else {
78 removeAll("content-length"); 102 removeAll("content-length");
79 } 103 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 307
284 _foldHeader(String name) { 308 _foldHeader(String name) {
285 if (name == "set-cookie" || 309 if (name == "set-cookie" ||
286 (_noFoldingHeaders != null && 310 (_noFoldingHeaders != null &&
287 _noFoldingHeaders.indexOf(name) != -1)) { 311 _noFoldingHeaders.indexOf(name) != -1)) {
288 return false; 312 return false;
289 } 313 }
290 return true; 314 return true;
291 } 315 }
292 316
293 void _finalize(String protocolVersion) { 317 void _finalize() {
294 // If the content length is not known make sure chunked transfer 318 // If the content length is not known make sure chunked transfer
295 // encoding is used for HTTP 1.1. 319 // encoding is used for HTTP 1.1.
296 if (contentLength < 0 && protocolVersion == "1.1") { 320 if (contentLength < 0 && protocolVersion == "1.1") {
297 chunkedTransferEncoding = true; 321 chunkedTransferEncoding = true;
298 } 322 }
299 // If a Transfer-Encoding header field is present the 323 // If a Transfer-Encoding header field is present the
300 // Content-Length header MUST NOT be sent (RFC 2616 section 4.4). 324 // Content-Length header MUST NOT be sent (RFC 2616 section 4.4).
301 if (chunkedTransferEncoding && 325 if (chunkedTransferEncoding &&
302 contentLength >= 0 && 326 contentLength >= 0 &&
303 protocolVersion == "1.1") { 327 protocolVersion == "1.1") {
304 contentLength = -1; 328 contentLength = -1;
305 } 329 }
306 _mutable = false; 330 _mutable = false;
307 } 331 }
308 332
309 _write(_HttpConnectionBase connection) { 333 _write(IOSink sink) {
310 final COLONSP = const [_CharCode.COLON, _CharCode.SP]; 334 final COLONSP = const [_CharCode.COLON, _CharCode.SP];
311 final COMMASP = const [_CharCode.COMMA, _CharCode.SP]; 335 final COMMASP = const [_CharCode.COMMA, _CharCode.SP];
312 final CRLF = const [_CharCode.CR, _CharCode.LF]; 336 final CRLF = const [_CharCode.CR, _CharCode.LF];
313 337
314 var bufferSize = 16 * 1024; 338 var bufferSize = 16 * 1024;
315 var buffer = new Uint8List(bufferSize); 339 var buffer = new Uint8List(bufferSize);
316 var bufferPos = 0; 340 var bufferPos = 0;
317 341
318 void writeBuffer() { 342 void writeBuffer() {
319 connection._writeFrom(buffer, 0, bufferPos); 343 sink.add(buffer.getRange(0, bufferPos));
320 bufferPos = 0; 344 bufferPos = 0;
321 } 345 }
322 346
323 // Format headers. 347 // Format headers.
324 _headers.forEach((String name, List<String> values) { 348 _headers.forEach((String name, List<String> values) {
325 bool fold = _foldHeader(name); 349 bool fold = _foldHeader(name);
326 List<int> nameData; 350 List<int> nameData;
327 nameData = name.charCodes; 351 nameData = name.charCodes;
328 int nameDataLen = nameData.length; 352 int nameDataLen = nameData.length;
329 if (nameDataLen + 2 > bufferSize - bufferPos) writeBuffer(); 353 if (nameDataLen + 2 > bufferSize - bufferPos) writeBuffer();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 sb.add(": "); 398 sb.add(": ");
375 } 399 }
376 } 400 }
377 sb.add(values[i]); 401 sb.add(values[i]);
378 } 402 }
379 sb.add("\n"); 403 sb.add("\n");
380 }); 404 });
381 return sb.toString(); 405 return sb.toString();
382 } 406 }
383 407
408 List<Cookie> _parseCookies() {
409 // Parse a Cookie header value according to the rules in RFC 6265.
410 var cookies = new List<Cookie>();
411 void parseCookieString(String s) {
412 int index = 0;
413
414 bool done() => index == s.length;
415
416 void skipWS() {
417 while (!done()) {
418 if (s[index] != " " && s[index] != "\t") return;
419 index++;
420 }
421 }
422
423 String parseName() {
424 int start = index;
425 while (!done()) {
426 if (s[index] == " " || s[index] == "\t" || s[index] == "=") break;
427 index++;
428 }
429 return s.substring(start, index).toLowerCase();
430 }
431
432 String parseValue() {
433 int start = index;
434 while (!done()) {
435 if (s[index] == " " || s[index] == "\t" || s[index] == ";") break;
436 index++;
437 }
438 return s.substring(start, index).toLowerCase();
439 }
440
441 void expect(String expected) {
442 if (done()) {
443 throw new HttpException("Failed to parse header value [$s]");
444 }
445 if (s[index] != expected) {
446 throw new HttpException("Failed to parse header value [$s]");
447 }
448 index++;
449 }
450
451 while (!done()) {
452 skipWS();
453 if (done()) return;
454 String name = parseName();
455 skipWS();
456 expect("=");
457 skipWS();
458 String value = parseValue();
459 cookies.add(new _Cookie(name, value));
460 skipWS();
461 if (done()) return;
462 expect(";");
463 }
464 }
465 List<String> values = this["cookie"];
466 if (values != null) {
467 values.forEach((headerValue) => parseCookieString(headerValue));
468 }
469 return cookies;
470 }
471
472
384 bool _mutable = true; // Are the headers currently mutable? 473 bool _mutable = true; // Are the headers currently mutable?
385 Map<String, List<String>> _headers; 474 Map<String, List<String>> _headers;
386 List<String> _noFoldingHeaders; 475 List<String> _noFoldingHeaders;
387 476
388 int _contentLength = -1; 477 int _contentLength = -1;
389 bool _chunkedTransferEncoding = false; 478 bool _chunkedTransferEncoding = false;
479 final String protocolVersion;
390 String _host; 480 String _host;
391 int _port; 481 int _port;
392 } 482 }
393 483
394 484
395 class _HeaderValue implements HeaderValue { 485 class _HeaderValue implements HeaderValue {
396 _HeaderValue([String this.value = ""]); 486 _HeaderValue([String this.value = ""]);
397 487
398 _HeaderValue.fromString(String value, {this.parameterSeparator: ";"}) { 488 _HeaderValue.fromString(String value, {this.parameterSeparator: ";"}) {
399 // Parse the string. 489 // Parse the string.
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 773
684 String name; 774 String name;
685 String value; 775 String value;
686 DateTime expires; 776 DateTime expires;
687 int maxAge; 777 int maxAge;
688 String domain; 778 String domain;
689 String path; 779 String path;
690 bool httpOnly = false; 780 bool httpOnly = false;
691 bool secure = false; 781 bool secure = false;
692 } 782 }
OLDNEW
« no previous file with comments | « sdk/lib/io/http.dart ('k') | sdk/lib/io/http_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698