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

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

Issue 12655003: Buffer the entire http header to one packet, and buffer other data in chunks of 4-16 kb. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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_headers.dart ('k') | tests/standalone/io/http_10_test.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) 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 _HttpIncoming extends Stream<List<int>> { 7 class _HttpIncoming extends Stream<List<int>> {
8 final int _transferLength; 8 final int _transferLength;
9 final Completer _dataCompleter = new Completer(); 9 final Completer _dataCompleter = new Completer();
10 Stream<List<int>> _stream; 10 Stream<List<int>> _stream;
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip)); 442 _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip));
443 _ioSink.encoding = encoding; 443 _ioSink.encoding = encoding;
444 } 444 }
445 445
446 Future _consume(IOSink ioSink, Stream<List<int>> stream, bool asGZip) { 446 Future _consume(IOSink ioSink, Stream<List<int>> stream, bool asGZip) {
447 int contentLength = headers.contentLength; 447 int contentLength = headers.contentLength;
448 if (_ignoreBody) { 448 if (_ignoreBody) {
449 ioSink.close(); 449 ioSink.close();
450 return stream.reduce(null, (x, y) {}).then((_) => this); 450 return stream.reduce(null, (x, y) {}).then((_) => this);
451 } 451 }
452 stream = stream.transform(new _BufferTransformer());
452 if (headers.chunkedTransferEncoding) { 453 if (headers.chunkedTransferEncoding) {
453 if (asGZip) { 454 if (asGZip) {
454 stream = stream.transform(new ZLibDeflater(gzip: true, level: 6)); 455 stream = stream.transform(new ZLibDeflater(gzip: true, level: 6));
455 } 456 }
456 stream = stream.transform(new _ChunkedTransformer()); 457 stream = stream.transform(new _ChunkedTransformer());
457 } else if (contentLength >= 0) { 458 } else if (contentLength >= 0) {
458 stream = stream.transform(new _ContentLengthValidator(contentLength)); 459 stream = stream.transform(new _ContentLengthValidator(contentLength));
459 } 460 }
460 return stream.pipe(ioSink).then((_) => this); 461 return stream.pipe(ioSink).then((_) => this);
461 } 462 }
462 463
463 void _writeHeader(); // TODO(ajohnsen): Better name. 464 void _writeHeader(); // TODO(ajohnsen): Better name.
464 } 465 }
465 466
466 467
467 class _HttpOutboundConsumer implements StreamConsumer { 468 class _HttpOutboundConsumer implements StreamConsumer {
468 Function _consume; 469 Function _consume;
469 IOSink _ioSink; 470 IOSink _ioSink;
470 bool _asGZip; 471 bool _asGZip;
471 _HttpOutboundConsumer(IOSink this._ioSink, 472 _HttpOutboundConsumer(IOSink this._ioSink,
472 Function this._consume, 473 Function this._consume,
473 bool this._asGZip); 474 bool this._asGZip);
474 475
475 Future consume(var stream) => _consume(_ioSink, stream, _asGZip); 476 Future consume(var stream) => _consume(_ioSink, stream, _asGZip);
476 } 477 }
477 478
478 479
480 class _BufferTransformer extends StreamEventTransformer<List<int>, List<int>> {
481 const int MIN_CHUNK_SIZE = 4 * 1024;
482 const int MAX_BUFFER_SIZE = 16 * 1024;
483
484 final _BufferList _buffer = new _BufferList();
485
486 void handleData(List<int> data, EventSink<List<int>> sink) {
487 // TODO(ajohnsen): Use timeout?
488 if (data.length == 0) return;
489 if (data.length >= MIN_CHUNK_SIZE) {
490 flush(sink);
491 sink.add(data);
492 } else {
493 _buffer.add(data);
494 if (_buffer.length >= MAX_BUFFER_SIZE) {
495 flush(sink);
496 }
497 }
498 }
499
500 void handleDone(EventSink<List<int>> sink) {
501 flush(sink);
502 sink.close();
503 }
504
505 void flush(EventSink<List<int>> sink) {
506 if (_buffer.length > 0) {
507 sink.add(_buffer.readBytes());
508 _buffer.clear();
509 }
510 }
511 }
512
513
479 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> 514 class _HttpResponse extends _HttpOutboundMessage<HttpResponse>
480 implements HttpResponse { 515 implements HttpResponse {
481 int statusCode = 200; 516 int statusCode = 200;
482 String _reasonPhrase; 517 String _reasonPhrase;
483 List<Cookie> _cookies; 518 List<Cookie> _cookies;
484 _HttpRequest _httpRequest; 519 _HttpRequest _httpRequest;
485 520
486 _HttpResponse(String protocolVersion, 521 _HttpResponse(String protocolVersion,
487 _HttpOutgoing _outgoing) 522 _HttpOutgoing _outgoing)
488 : super(protocolVersion, _outgoing); 523 : super(protocolVersion, _outgoing);
(...skipping 18 matching lines...) Expand all
507 done.catchError((_) { 542 done.catchError((_) {
508 // Catch any error on done, as they automatically will be propegated to 543 // Catch any error on done, as they automatically will be propegated to
509 // the websocket. 544 // the websocket.
510 }); 545 });
511 return future; 546 return future;
512 } 547 }
513 548
514 HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; 549 HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo;
515 550
516 void _writeHeader() { 551 void _writeHeader() {
517 writeSP() => _ioSink.writeBytes([_CharCode.SP]); 552 var buffer = new _BufferList();
518 writeCRLF() => _ioSink.writeBytes([_CharCode.CR, _CharCode.LF]); 553 writeSP() => buffer.add(const [_CharCode.SP]);
554 writeCRLF() => buffer.add(const [_CharCode.CR, _CharCode.LF]);
519 555
520 // Write status line. 556 // Write status line.
521 if (headers.protocolVersion == "1.1") { 557 if (headers.protocolVersion == "1.1") {
522 _ioSink.writeBytes(_Const.HTTP11); 558 buffer.add(_Const.HTTP11);
523 } else { 559 } else {
524 _ioSink.writeBytes(_Const.HTTP10); 560 buffer.add(_Const.HTTP10);
525 } 561 }
526 writeSP(); 562 writeSP();
527 _ioSink.write(statusCode.toString()); 563 buffer.add(statusCode.toString().codeUnits);
528 writeSP(); 564 writeSP();
529 _ioSink.write(reasonPhrase); 565 buffer.add(reasonPhrase.codeUnits);
530 writeCRLF(); 566 writeCRLF();
531 567
532 var session = _httpRequest._session; 568 var session = _httpRequest._session;
533 if (session != null && !session._destroyed) { 569 if (session != null && !session._destroyed) {
534 // Mark as not new. 570 // Mark as not new.
535 session._isNew = false; 571 session._isNew = false;
536 // Make sure we only send the current session id. 572 // Make sure we only send the current session id.
537 bool found = false; 573 bool found = false;
538 for (int i = 0; i < cookies.length; i++) { 574 for (int i = 0; i < cookies.length; i++) {
539 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { 575 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
(...skipping 13 matching lines...) Expand all
553 // Add all the cookies set to the headers. 589 // Add all the cookies set to the headers.
554 if (_cookies != null) { 590 if (_cookies != null) {
555 _cookies.forEach((cookie) { 591 _cookies.forEach((cookie) {
556 headers.add(HttpHeaders.SET_COOKIE, cookie); 592 headers.add(HttpHeaders.SET_COOKIE, cookie);
557 }); 593 });
558 } 594 }
559 595
560 headers._finalize(); 596 headers._finalize();
561 597
562 // Write headers. 598 // Write headers.
563 headers._write(_ioSink); 599 headers._write(buffer);
564 writeCRLF(); 600 writeCRLF();
601 _ioSink.writeBytes(buffer.readBytes());
565 } 602 }
566 603
567 String _findReasonPhrase(int statusCode) { 604 String _findReasonPhrase(int statusCode) {
568 if (_reasonPhrase != null) { 605 if (_reasonPhrase != null) {
569 return _reasonPhrase; 606 return _reasonPhrase;
570 } 607 }
571 608
572 switch (statusCode) { 609 switch (statusCode) {
573 case HttpStatus.CONTINUE: return "Continue"; 610 case HttpStatus.CONTINUE: return "Continue";
574 case HttpStatus.SWITCHING_PROTOCOLS: return "Switching Protocols"; 611 case HttpStatus.SWITCHING_PROTOCOLS: return "Switching Protocols";
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 onError: (e) { 740 onError: (e) {
704 _responseCompleter.completeError(e); 741 _responseCompleter.completeError(e);
705 }); 742 });
706 } 743 }
707 744
708 void _onError(AsyncError error) { 745 void _onError(AsyncError error) {
709 _responseCompleter.completeError(error); 746 _responseCompleter.completeError(error);
710 } 747 }
711 748
712 void _writeHeader() { 749 void _writeHeader() {
713 writeSP() => _ioSink.writeBytes([_CharCode.SP]); 750 var buffer = new _BufferList();
714 writeCRLF() => _ioSink.writeBytes([_CharCode.CR, _CharCode.LF]); 751 writeSP() => buffer.add(const [_CharCode.SP]);
752 writeCRLF() => buffer.add(const [_CharCode.CR, _CharCode.LF]);
715 753
716 _ioSink.write(method); 754 buffer.add(method.codeUnits);
717 writeSP(); 755 writeSP();
718 // Send the path for direct connections and the whole URL for 756 // Send the path for direct connections and the whole URL for
719 // proxy connections. 757 // proxy connections.
720 if (!_usingProxy) { 758 if (!_usingProxy) {
721 String path = uri.path; 759 String path = uri.path;
722 if (path.length == 0) path = "/"; 760 if (path.length == 0) path = "/";
723 if (uri.query != "") { 761 if (uri.query != "") {
724 if (uri.fragment != "") { 762 if (uri.fragment != "") {
725 path = "${path}?${uri.query}#${uri.fragment}"; 763 path = "${path}?${uri.query}#${uri.fragment}";
726 } else { 764 } else {
727 path = "${path}?${uri.query}"; 765 path = "${path}?${uri.query}";
728 } 766 }
729 } 767 }
730 _ioSink.write(path); 768 buffer.add(path.codeUnits);
731 } else { 769 } else {
732 _ioSink.write(uri.toString()); 770 buffer.add(uri.toString().codeUnits);
733 } 771 }
734 writeSP(); 772 writeSP();
735 _ioSink.writeBytes(_Const.HTTP11); 773 buffer.add(_Const.HTTP11);
736 writeCRLF(); 774 writeCRLF();
737 775
738 // Add the cookies to the headers. 776 // Add the cookies to the headers.
739 if (!cookies.isEmpty) { 777 if (!cookies.isEmpty) {
740 StringBuffer sb = new StringBuffer(); 778 StringBuffer sb = new StringBuffer();
741 for (int i = 0; i < cookies.length; i++) { 779 for (int i = 0; i < cookies.length; i++) {
742 if (i > 0) sb.write("; "); 780 if (i > 0) sb.write("; ");
743 sb.write(cookies[i].name); 781 sb.write(cookies[i].name);
744 sb.write("="); 782 sb.write("=");
745 sb.write(cookies[i].value); 783 sb.write(cookies[i].value);
746 } 784 }
747 headers.add(HttpHeaders.COOKIE, sb.toString()); 785 headers.add(HttpHeaders.COOKIE, sb.toString());
748 } 786 }
749 787
750 headers._finalize(); 788 headers._finalize();
751 789
752 // Write headers. 790 // Write headers.
753 headers._write(_ioSink); 791 headers._write(buffer);
754 writeCRLF(); 792 writeCRLF();
793 _ioSink.writeBytes(buffer.readBytes());
755 } 794 }
756 } 795 }
757 796
758 797
759 // Transformer that transforms data to HTTP Chunked Encoding. 798 // Transformer that transforms data to HTTP Chunked Encoding.
760 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> { 799 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> {
761 void handleData(List<int> data, EventSink<List<int>> sink) { 800 void handleData(List<int> data, EventSink<List<int>> sink) {
762 sink.add(_chunkHeader(data.length)); 801 sink.add(_chunkHeader(data.length));
763 if (data.length > 0) sink.add(data); 802 if (data.length > 0) sink.add(data);
764 sink.add(_chunkFooter); 803 sink.add(_chunkFooter);
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 1709
1671 1710
1672 class _RedirectInfo implements RedirectInfo { 1711 class _RedirectInfo implements RedirectInfo {
1673 const _RedirectInfo(int this.statusCode, 1712 const _RedirectInfo(int this.statusCode,
1674 String this.method, 1713 String this.method,
1675 Uri this.location); 1714 Uri this.location);
1676 final int statusCode; 1715 final int statusCode;
1677 final String method; 1716 final String method;
1678 final Uri location; 1717 final Uri location;
1679 } 1718 }
OLDNEW
« no previous file with comments | « sdk/lib/io/http_headers.dart ('k') | tests/standalone/io/http_10_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698