OLD | NEW |
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 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 _controller.close(); | 643 _controller.close(); |
644 return _closeCompleter.future.then((_) => closeOutbound()); | 644 return _closeCompleter.future.then((_) => closeOutbound()); |
645 } | 645 } |
646 } | 646 } |
647 | 647 |
648 | 648 |
649 class _BufferTransformer extends StreamEventTransformer<List<int>, List<int>> { | 649 class _BufferTransformer extends StreamEventTransformer<List<int>, List<int>> { |
650 static const int MIN_CHUNK_SIZE = 4 * 1024; | 650 static const int MIN_CHUNK_SIZE = 4 * 1024; |
651 static const int MAX_BUFFER_SIZE = 16 * 1024; | 651 static const int MAX_BUFFER_SIZE = 16 * 1024; |
652 | 652 |
653 final _BufferList _buffer = new _BufferList(); | 653 final BytesBuilder _builder = new BytesBuilder(); |
654 | 654 |
655 void handleData(List<int> data, EventSink<List<int>> sink) { | 655 void handleData(List<int> data, EventSink<List<int>> sink) { |
656 // TODO(ajohnsen): Use timeout? | 656 // TODO(ajohnsen): Use timeout? |
657 if (data.length == 0) return; | 657 if (data.length == 0) return; |
658 if (data.length >= MIN_CHUNK_SIZE) { | 658 if (data.length >= MIN_CHUNK_SIZE) { |
659 flush(sink); | 659 flush(sink); |
660 sink.add(data); | 660 sink.add(data); |
661 } else { | 661 } else { |
662 _buffer.add(data); | 662 _builder.add(data); |
663 if (_buffer.length >= MAX_BUFFER_SIZE) { | 663 if (_builder.length >= MAX_BUFFER_SIZE) { |
664 flush(sink); | 664 flush(sink); |
665 } | 665 } |
666 } | 666 } |
667 } | 667 } |
668 | 668 |
669 void handleDone(EventSink<List<int>> sink) { | 669 void handleDone(EventSink<List<int>> sink) { |
670 flush(sink); | 670 flush(sink); |
671 sink.close(); | 671 sink.close(); |
672 } | 672 } |
673 | 673 |
674 void flush(EventSink<List<int>> sink) { | 674 void flush(EventSink<List<int>> sink) { |
675 if (_buffer.length > 0) { | 675 if (_builder.length > 0) { |
676 sink.add(_buffer.readBytes()); | 676 // takeBytes will clear the BytesBuilder. |
677 _buffer.clear(); | 677 sink.add(_builder.takeBytes()); |
678 } | 678 } |
679 } | 679 } |
680 } | 680 } |
681 | 681 |
682 | 682 |
683 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> | 683 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> |
684 implements HttpResponse { | 684 implements HttpResponse { |
685 int statusCode = 200; | 685 int statusCode = 200; |
686 String _reasonPhrase; | 686 String _reasonPhrase; |
687 List<Cookie> _cookies; | 687 List<Cookie> _cookies; |
(...skipping 27 matching lines...) Expand all Loading... |
715 done.catchError((_) { | 715 done.catchError((_) { |
716 // Catch any error on done, as they automatically will be | 716 // Catch any error on done, as they automatically will be |
717 // propagated to the websocket. | 717 // propagated to the websocket. |
718 }); | 718 }); |
719 return future; | 719 return future; |
720 } | 720 } |
721 | 721 |
722 HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; | 722 HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; |
723 | 723 |
724 void _writeHeader() { | 724 void _writeHeader() { |
725 var buffer = new _BufferList(); | 725 var builder = new BytesBuilder(); |
726 writeSP() => buffer.add(const [_CharCode.SP]); | 726 writeSP() => builder.add(const [_CharCode.SP]); |
727 writeCRLF() => buffer.add(const [_CharCode.CR, _CharCode.LF]); | 727 writeCRLF() => builder.add(const [_CharCode.CR, _CharCode.LF]); |
728 | 728 |
729 // Write status line. | 729 // Write status line. |
730 if (headers.protocolVersion == "1.1") { | 730 if (headers.protocolVersion == "1.1") { |
731 buffer.add(_Const.HTTP11); | 731 builder.add(_Const.HTTP11); |
732 } else { | 732 } else { |
733 buffer.add(_Const.HTTP10); | 733 builder.add(_Const.HTTP10); |
734 } | 734 } |
735 writeSP(); | 735 writeSP(); |
736 buffer.add(statusCode.toString().codeUnits); | 736 builder.add(statusCode.toString().codeUnits); |
737 writeSP(); | 737 writeSP(); |
738 buffer.add(reasonPhrase.codeUnits); | 738 builder.add(reasonPhrase.codeUnits); |
739 writeCRLF(); | 739 writeCRLF(); |
740 | 740 |
741 var session = _httpRequest._session; | 741 var session = _httpRequest._session; |
742 if (session != null && !session._destroyed) { | 742 if (session != null && !session._destroyed) { |
743 // Mark as not new. | 743 // Mark as not new. |
744 session._isNew = false; | 744 session._isNew = false; |
745 // Make sure we only send the current session id. | 745 // Make sure we only send the current session id. |
746 bool found = false; | 746 bool found = false; |
747 for (int i = 0; i < cookies.length; i++) { | 747 for (int i = 0; i < cookies.length; i++) { |
748 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { | 748 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { |
(...skipping 13 matching lines...) Expand all Loading... |
762 // Add all the cookies set to the headers. | 762 // Add all the cookies set to the headers. |
763 if (_cookies != null) { | 763 if (_cookies != null) { |
764 _cookies.forEach((cookie) { | 764 _cookies.forEach((cookie) { |
765 headers.add(HttpHeaders.SET_COOKIE, cookie); | 765 headers.add(HttpHeaders.SET_COOKIE, cookie); |
766 }); | 766 }); |
767 } | 767 } |
768 | 768 |
769 headers._finalize(); | 769 headers._finalize(); |
770 | 770 |
771 // Write headers. | 771 // Write headers. |
772 headers._write(buffer); | 772 headers._write(builder); |
773 writeCRLF(); | 773 writeCRLF(); |
774 _headersSink.add(buffer.readBytes()); | 774 _headersSink.add(builder.takeBytes()); |
775 } | 775 } |
776 | 776 |
777 String _findReasonPhrase(int statusCode) { | 777 String _findReasonPhrase(int statusCode) { |
778 if (_reasonPhrase != null) { | 778 if (_reasonPhrase != null) { |
779 return _reasonPhrase; | 779 return _reasonPhrase; |
780 } | 780 } |
781 | 781 |
782 switch (statusCode) { | 782 switch (statusCode) { |
783 case HttpStatus.CONTINUE: return "Continue"; | 783 case HttpStatus.CONTINUE: return "Continue"; |
784 case HttpStatus.SWITCHING_PROTOCOLS: return "Switching Protocols"; | 784 case HttpStatus.SWITCHING_PROTOCOLS: return "Switching Protocols"; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 if (_httpClientConnection._proxyTunnel) { | 960 if (_httpClientConnection._proxyTunnel) { |
961 return uriStartingFromPath(); | 961 return uriStartingFromPath(); |
962 } else { | 962 } else { |
963 return uri.toString(); | 963 return uri.toString(); |
964 } | 964 } |
965 } | 965 } |
966 } | 966 } |
967 } | 967 } |
968 | 968 |
969 void _writeHeader() { | 969 void _writeHeader() { |
970 var buffer = new _BufferList(); | 970 var builder = new BytesBuilder(); |
971 | 971 |
972 writeSP() => buffer.add(const [_CharCode.SP]); | 972 writeSP() => builder.add(const [_CharCode.SP]); |
973 | 973 |
974 writeCRLF() => buffer.add(const [_CharCode.CR, _CharCode.LF]); | 974 writeCRLF() => builder.add(const [_CharCode.CR, _CharCode.LF]); |
975 | 975 |
976 // Write the request method. | 976 // Write the request method. |
977 buffer.add(method.codeUnits); | 977 builder.add(method.codeUnits); |
978 writeSP(); | 978 writeSP(); |
979 // Write the request URI. | 979 // Write the request URI. |
980 buffer.add(_requestUri().codeUnits); | 980 builder.add(_requestUri().codeUnits); |
981 writeSP(); | 981 writeSP(); |
982 // Write HTTP/1.1. | 982 // Write HTTP/1.1. |
983 buffer.add(_Const.HTTP11); | 983 builder.add(_Const.HTTP11); |
984 writeCRLF(); | 984 writeCRLF(); |
985 | 985 |
986 // Add the cookies to the headers. | 986 // Add the cookies to the headers. |
987 if (!cookies.isEmpty) { | 987 if (!cookies.isEmpty) { |
988 StringBuffer sb = new StringBuffer(); | 988 StringBuffer sb = new StringBuffer(); |
989 for (int i = 0; i < cookies.length; i++) { | 989 for (int i = 0; i < cookies.length; i++) { |
990 if (i > 0) sb.write("; "); | 990 if (i > 0) sb.write("; "); |
991 sb.write(cookies[i].name); | 991 sb.write(cookies[i].name); |
992 sb.write("="); | 992 sb.write("="); |
993 sb.write(cookies[i].value); | 993 sb.write(cookies[i].value); |
994 } | 994 } |
995 headers.add(HttpHeaders.COOKIE, sb.toString()); | 995 headers.add(HttpHeaders.COOKIE, sb.toString()); |
996 } | 996 } |
997 | 997 |
998 headers._finalize(); | 998 headers._finalize(); |
999 | 999 |
1000 // Write headers. | 1000 // Write headers. |
1001 headers._write(buffer); | 1001 headers._write(builder); |
1002 writeCRLF(); | 1002 writeCRLF(); |
1003 _headersSink.add(buffer.readBytes()); | 1003 _headersSink.add(builder.takeBytes()); |
1004 } | 1004 } |
1005 } | 1005 } |
1006 | 1006 |
1007 | 1007 |
1008 // Transformer that transforms data to HTTP Chunked Encoding. | 1008 // Transformer that transforms data to HTTP Chunked Encoding. |
1009 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> { | 1009 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> { |
1010 int _pendingFooter = 0; | 1010 int _pendingFooter = 0; |
1011 | 1011 |
1012 void handleData(List<int> data, EventSink<List<int>> sink) { | 1012 void handleData(List<int> data, EventSink<List<int>> sink) { |
1013 sink.add(_chunkHeader(data.length)); | 1013 sink.add(_chunkHeader(data.length)); |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2404 final Uri location; | 2404 final Uri location; |
2405 } | 2405 } |
2406 | 2406 |
2407 String _getHttpVersion() { | 2407 String _getHttpVersion() { |
2408 var version = Platform.version; | 2408 var version = Platform.version; |
2409 // Only include major and minor version numbers. | 2409 // Only include major and minor version numbers. |
2410 int index = version.indexOf('.', version.indexOf('.') + 1); | 2410 int index = version.indexOf('.', version.indexOf('.') + 1); |
2411 version = version.substring(0, index); | 2411 version = version.substring(0, index); |
2412 return 'Dart/$version (dart:io)'; | 2412 return 'Dart/$version (dart:io)'; |
2413 } | 2413 } |
OLD | NEW |