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

Side by Side Diff: samples/chat/http_impl.dart

Issue 9495007: Prepare the HTTP library for inclusion in the standalone VM (step 2) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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
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 // Global constants. 5 // Global constants.
6 class _Const { 6 class _Const {
7 // Bytes for "HTTP/1.0". 7 // Bytes for "HTTP/1.0".
8 static final HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48]; 8 static final HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48];
9 // Bytes for "HTTP/1.1". 9 // Bytes for "HTTP/1.1".
10 static final HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49]; 10 static final HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49];
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 StringBuffer _headerField; 399 StringBuffer _headerField;
400 StringBuffer _headerValue; 400 StringBuffer _headerValue;
401 401
402 int _contentLength; 402 int _contentLength;
403 bool _keepAlive; 403 bool _keepAlive;
404 bool _chunked; 404 bool _chunked;
405 405
406 int _remainingContent; 406 int _remainingContent;
407 407
408 // Callbacks. 408 // Callbacks.
409 var requestStart; 409 Function requestStart;
410 var responseStart; 410 Function responseStart;
411 var headerReceived; 411 Function headerReceived;
412 var headersComplete; 412 Function headersComplete;
413 var dataReceived; 413 Function dataReceived;
414 var dataEnd; 414 Function dataEnd;
415 } 415 }
416 416
417 417
418 // Utility class which can deliver bytes one by one from a number of
419 // buffers added.
420 class _BufferList {
421 _BufferList() : _index = 0, _length = 0, _buffers = new Queue();
422
423 void add(List<int> buffer) {
424 _buffers.addLast(buffer);
425 _length += buffer.length;
426 }
427
428 int next() {
429 int value = _buffers.first()[_index++];
430 _length--;
431 if (_index == _buffers.first().length) {
432 _buffers.removeFirst();
433 _index = 0;
434 }
435 return value;
436 }
437
438 int get length() => _length;
439
440 int _length;
441 Queue<List<int>> _buffers;
442 int _index;
443 }
444
445
446 // Utility class for decoding UTF-8 from data delivered as a stream of
447 // bytes.
448 class _UTF8Decoder {
449 _UTF8Decoder()
450 : _bufferList = new _BufferList(),
451 _result = new StringBuffer();
452
453 // Add UTF-8 encoded data.
454 int writeList(List<int> buffer) {
455 _bufferList.add(buffer);
456 // Only process as much data as we know is safe.
457 while (_bufferList.length >= 4) {
458 _processNext();
459 }
460 }
461
462 // Return the decoded string.
463 String toString() {
464 // Process any leftover data.
465 while (_bufferList.length > 0) {
466 _processNext();
467 }
468 return _result.toString();
469 }
470
471 // Process the next UTF-8 encoded character.
472 void _processNext() {
473 int value = _bufferList.next() & 0xFF;
474 if ((value & 0x80) == 0x80) {
475 int additionalBytes;
476 if ((value & 0xe0) == 0xc0) { // 110xxxxx
477 value = value & 0x1F;
478 additionalBytes = 1;
479 } else if ((value & 0xf0) == 0xe0) { // 1110xxxx
480 value = value & 0x0F;
481 additionalBytes = 2;
482 } else { // 11110xxx
483 value = value & 0x07;
484 additionalBytes = 3;
485 }
486 for (int i = 0; i < additionalBytes; i++) {
487 int byte = _bufferList.next();
488 value = value << 6 | (byte & 0x3F);
489 }
490 }
491 _result.addCharCode(value);
492 }
493
494 _BufferList _bufferList;
495 StringBuffer _result;
496 }
497
498
499 // Utility class for encoding a string into UTF-8 byte stream. 418 // Utility class for encoding a string into UTF-8 byte stream.
500 class _UTF8Encoder { 419 class _UTF8Encoder {
501 static List<int> encodeString(String string) { 420 static List<int> encodeString(String string) {
502 int size = _encodingSize(string); 421 int size = _encodingSize(string);
503 ByteArray result = new ByteArray(size); 422 ByteArray result = new ByteArray(size);
504 _encodeString(string, result); 423 _encodeString(string, result);
505 return result; 424 return result;
506 } 425 }
507 426
508 static int _encodingSize(String string) => _encodeString(string, null); 427 static int _encodingSize(String string) => _encodeString(string, null);
(...skipping 28 matching lines...) Expand all
537 } 456 }
538 } else { 457 } else {
539 pos += additionalBytes; 458 pos += additionalBytes;
540 } 459 }
541 } 460 }
542 return pos; 461 return pos;
543 } 462 }
544 } 463 }
545 464
546 465
547 class _HTTPRequestOrResponse { 466 class _HTTPRequestResponseBase {
548 _HTTPRequestOrResponse(_HTTPConnectionBase this._httpConnection) 467 _HTTPRequestResponseBase(_HTTPConnectionBase this._httpConnection)
549 : _contentLength = -1, 468 : _contentLength = -1,
550 _keepAlive = false, 469 _keepAlive = false,
551 _headers = new Map(); 470 _headers = new Map();
552 471
553 int get contentLength() => _contentLength; 472 int get contentLength() => _contentLength;
554 bool get keepAlive() => _keepAlive; 473 bool get keepAlive() => _keepAlive;
555 474
556 void _setHeader(String name, String value) { 475 void _setHeader(String name, String value) {
557 _headers[name] = value; 476 _headers[name] = value;
558 } 477 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 void _writeCRLF() { 553 void _writeCRLF() {
635 final CRLF = const [_CharCode.CR, _CharCode.LF]; 554 final CRLF = const [_CharCode.CR, _CharCode.LF];
636 _httpConnection.outputStream.write(CRLF); 555 _httpConnection.outputStream.write(CRLF);
637 } 556 }
638 557
639 void _writeSP() { 558 void _writeSP() {
640 final SP = const [_CharCode.SP]; 559 final SP = const [_CharCode.SP];
641 _httpConnection.outputStream.write(SP); 560 _httpConnection.outputStream.write(SP);
642 } 561 }
643 562
644 void _dataReceivedHandler(List<int> data) {
645 // If no data received handler exists collect data as a string.
646 if (dataReceived != null) {
647 dataReceived(data);
648 } else {
649 if (_decoder == null) _decoder = new _UTF8Decoder();
650 _decoder.writeList(data);
651 }
652 }
653
654 void _dataEndHandler() {
655 if (dataEnd != null) {
656 // Pass the string collected if any.
657 dataEnd(_decoder != null ? _decoder.toString() : null);
658 }
659 }
660
661 _HTTPConnectionBase _httpConnection; 563 _HTTPConnectionBase _httpConnection;
662 Map<String, String> _headers; 564 Map<String, String> _headers;
663 565
664 // Length of the content body. If this is set to -1 (default value) 566 // Length of the content body. If this is set to -1 (default value)
665 // when starting to send data chunked transfer encoding will be 567 // when starting to send data chunked transfer encoding will be
666 // used. 568 // used.
667 int _contentLength; 569 int _contentLength;
668 bool _keepAlive; 570 bool _keepAlive;
669
670 _UTF8Decoder _decoder;
671
672 // Callbacks.
673 var dataReceived;
674 var dataEnd;
675 } 571 }
676 572
677 573
678 // Parsed HTTP request providing information on the HTTP headers. 574 // Parsed HTTP request providing information on the HTTP headers.
679 class _HTTPRequest extends _HTTPRequestOrResponse implements HTTPRequest { 575 class _HTTPRequest extends _HTTPRequestResponseBase implements HTTPRequest {
680 _HTTPRequest(_HTTPConnection connection) : super(connection); 576 _HTTPRequest(_HTTPConnection connection) : super(connection);
681 577
682 String get method() => _method; 578 String get method() => _method;
683 String get uri() => _uri; 579 String get uri() => _uri;
684 String get path() => _path; 580 String get path() => _path;
685 Map get headers() => _headers; 581 Map get headers() => _headers;
686 String get queryString() => _queryString; 582 String get queryString() => _queryString;
687 Map get queryParameters() => _queryParameters; 583 Map get queryParameters() => _queryParameters;
688 584
585 InputStream get inputStream() {
586 if (_inputStream == null) {
587 _inputStream = new _HTTPInputStream(this);
588 }
589 return _inputStream;
590 }
591
689 void _requestStartHandler(String method, String uri) { 592 void _requestStartHandler(String method, String uri) {
690 _method = method; 593 _method = method;
691 _uri = uri; 594 _uri = uri;
692 _parseRequestUri(uri); 595 _parseRequestUri(uri);
693 } 596 }
694 597
695 void _headerReceivedHandler(String name, String value) { 598 void _headerReceivedHandler(String name, String value) {
696 _setHeader(name, value); 599 _setHeader(name, value);
697 } 600 }
698 601
699 void _headersCompleteHandler() { 602 void _headersCompleteHandler() {
700 // Nothing to do. 603 // Prepare for receiving data.
604 _buffer = new _BufferList();
605 }
606
607 void _dataReceivedHandler(List<int> data) {
608 _buffer.add(data);
609 if (_inputStream != null) _inputStream._dataReceived();
610 }
611
612 void _dataEndHandler() {
613 if (_inputStream != null) _inputStream._closeReceived();
701 } 614 }
702 615
703 // Escaped characters in uri are expected to have been parsed. 616 // Escaped characters in uri are expected to have been parsed.
704 void _parseRequestUri(String uri) { 617 void _parseRequestUri(String uri) {
705 int position; 618 int position;
706 position = uri.indexOf("?", 0); 619 position = uri.indexOf("?", 0);
707 if (position == -1) { 620 if (position == -1) {
708 _path = HTTPUtil.decodeUrlEncodedString(_uri); 621 _path = HTTPUtil.decodeUrlEncodedString(_uri);
709 _queryString = null; 622 _queryString = null;
710 _queryParameters = new Map(); 623 _queryParameters = new Map();
711 } else { 624 } else {
712 _path = HTTPUtil.decodeUrlEncodedString(_uri.substring(0, position)); 625 _path = HTTPUtil.decodeUrlEncodedString(_uri.substring(0, position));
713 _queryString = _uri.substring(position + 1); 626 _queryString = _uri.substring(position + 1);
714 _queryParameters = HTTPUtil.splitQueryString(_queryString); 627 _queryParameters = HTTPUtil.splitQueryString(_queryString);
715 } 628 }
716 } 629 }
717 630
631 /*
632 * Delegate functions for the HTTPInputStream implementation.
Mads Ager (google) 2012/02/28 12:27:40 Just use '//' style comment?
Søren Gjesse 2012/02/28 13:03:42 Done.
633 */
634 int _streamAvailable() {
635 return _buffer.length;
636 }
637
638 List<int> _streamRead(int bytesToRead) {
639 return _buffer.readBytes(bytesToRead);
640 }
641
642 int _streamReadInto(List<int> buffer, int offset, int len) {
643 List<int> data = _buffer.readBytes(len);
644 buffer.setRange(offset, data.length, data);
645 }
646
718 String _method; 647 String _method;
719 String _uri; 648 String _uri;
720 String _path; 649 String _path;
721 String _queryString; 650 String _queryString;
722 Map<String, String> _queryParameters; 651 Map<String, String> _queryParameters;
652 _HTTPInputStream _inputStream;
653 _BufferList _buffer;
723 } 654 }
724 655
725 656
726 // HTTP response object for sending a HTTP response. 657 // HTTP response object for sending a HTTP response.
727 class _HTTPResponse extends _HTTPRequestOrResponse implements HTTPResponse { 658 class _HTTPResponse extends _HTTPRequestResponseBase implements HTTPResponse {
728 static final int START = 0; 659 static final int START = 0;
729 static final int HEADERS_SENT = 1; 660 static final int HEADERS_SENT = 1;
730 static final int DONE = 2; 661 static final int DONE = 2;
731 662
732 _HTTPResponse(_HTTPConnection httpConnection) 663 _HTTPResponse(_HTTPConnection httpConnection)
733 : super(httpConnection), 664 : super(httpConnection),
734 statusCode = HTTPStatus.OK, 665 statusCode = HTTPStatus.OK,
735 _state = START; 666 _state = START;
736 667
737 void set contentLength(int contentLength) { 668 void set contentLength(int contentLength) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 */ 705 */
775 bool _streamWrite(List<int> buffer, bool copyBuffer) { 706 bool _streamWrite(List<int> buffer, bool copyBuffer) {
776 _write(buffer, copyBuffer); 707 _write(buffer, copyBuffer);
777 } 708 }
778 709
779 bool _streamWriteFrom(List<int> buffer, int offset, int len) { 710 bool _streamWriteFrom(List<int> buffer, int offset, int len) {
780 _writeList(buffer, offset, len); 711 _writeList(buffer, offset, len);
781 } 712 }
782 713
783 void _streamClose() { 714 void _streamClose() {
715 _state = DONE;
784 // Stop tracking no pending write events. 716 // Stop tracking no pending write events.
785 _httpConnection.outputStream.noPendingWriteHandler = null; 717 _httpConnection.outputStream.noPendingWriteHandler = null;
786
787 // Ensure that any trailing data is written. 718 // Ensure that any trailing data is written.
788 _writeDone(); 719 _writeDone();
789 _state = DONE; 720 // If the connection is closing then close the output stream to
721 // fully close the socket.
722 if (_httpConnection._closing) {
723 _httpConnection.outputStream.close();
724 }
790 } 725 }
791 726
792 void _streamSetNoPendingWriteHandler(callback()) { 727 void _streamSetNoPendingWriteHandler(callback()) {
793 _httpConnection.outputStream.noPendingWriteHandler = callback; 728 if (_state != DONE) {
729 _httpConnection.outputStream.noPendingWriteHandler = callback;
730 }
794 } 731 }
795 732
796 void _streamSetCloseHandler(callback()) { 733 void _streamSetCloseHandler(callback()) {
797 // TODO(sgjesse): Handle this. 734 // TODO(sgjesse): Handle this.
798 } 735 }
799 736
800 void _streamSetErrorHandler(callback()) { 737 void _streamSetErrorHandler(callback()) {
801 // TODO(sgjesse): Handle this. 738 // TODO(sgjesse): Handle this.
802 } 739 }
803 740
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 } 824 }
888 825
889 // Response status code. 826 // Response status code.
890 int statusCode; 827 int statusCode;
891 String reasonPhrase; 828 String reasonPhrase;
892 _HTTPOutputStream _outputStream; 829 _HTTPOutputStream _outputStream;
893 int _state; 830 int _state;
894 } 831 }
895 832
896 833
834 class _HTTPInputStream extends _BaseDataInputStream implements InputStream {
835 _HTTPInputStream(_HTTPRequestResponseBase this._requestOrResponse) {
836 _checkScheduleCallbacks();
837 }
838
839 int available() {
840 return _requestOrResponse._streamAvailable();
841 }
842
843 void pipe(OutputStream output, [bool close = true]) {
844 _pipe(this, output, close: close);
845 }
846
847 List<int> _read(int bytesToRead) {
848 List<int> result = _requestOrResponse._streamRead(bytesToRead);
849 _checkScheduleCallbacks();
850 return result;
851 }
852
853 int _readInto(List<int> buffer, int offset, int len) {
854 List<int> result = _requestOrResponse._streamReadInto(buffer, offset, len);
855 _checkScheduleCallbacks();
856 return result;
857 }
858
859 void _close() {
860 // TODO(sgjesse): Handle this.
861 }
862
863 void _dataReceived() {
864 super._dataReceived();
865 }
866
867 _HTTPRequestResponseBase _requestOrResponse;
868 }
869
870
897 class _HTTPOutputStream implements OutputStream { 871 class _HTTPOutputStream implements OutputStream {
898 _HTTPOutputStream(_HTTPRequestOrResponse this._requestOrResponse); 872 _HTTPOutputStream(_HTTPRequestResponseBase this._requestOrResponse);
899 873
900 bool write(List<int> buffer, [bool copyBuffer = true]) => 874 bool write(List<int> buffer, [bool copyBuffer = true]) {
901 _requestOrResponse._streamWrite(buffer, copyBuffer); 875 return _requestOrResponse._streamWrite(buffer, copyBuffer);
876 }
902 877
903 bool writeFrom(List<int> buffer, [int offset = 0, int len]) => 878 bool writeFrom(List<int> buffer, [int offset = 0, int len]) {
904 _requestOrResponse._streamWriteFrom(buffer, offset, len); 879 return _requestOrResponse._streamWriteFrom(buffer, offset, len);
880 }
905 881
906 void close() => _requestOrResponse._streamClose(); 882 void close() {
883 _requestOrResponse._streamClose();
884 }
907 885
908 void destroy() { throw "Not implemented"; } 886 void destroy() {
887 throw "Not implemented";
888 }
909 889
910 void set noPendingWriteHandler(void callback()) => 890 void set noPendingWriteHandler(void callback()) {
911 _requestOrResponse._streamSetNoPendingWriteHandler(callback); 891 _requestOrResponse._streamSetNoPendingWriteHandler(callback);
892 }
912 893
913 void set closeHandler(void callback()) => 894 void set closeHandler(void callback()) {
914 _requestOrResponse._streamSetCloseHandler(callback); 895 _requestOrResponse._streamSetCloseHandler(callback);
896 }
915 897
916 void set errorHandler(void callback()) => 898 void set errorHandler(void callback()) {
917 _requestOrResponse._streamSetErrorHandler(callback); 899 _requestOrResponse._streamSetErrorHandler(callback);
900 }
918 901
919 _HTTPRequestOrResponse _requestOrResponse; 902 _HTTPRequestResponseBase _requestOrResponse;
920 } 903 }
921 904
922 905
923 class _HTTPConnectionBase { 906 class _HTTPConnectionBase {
924 _HTTPConnectionBase() : _sendBuffers = new Queue(), 907 _HTTPConnectionBase() : _sendBuffers = new Queue(),
925 _httpParser = new HTTPParser(); 908 _httpParser = new HTTPParser();
926 909
927 void _connectionEstablished(Socket socket) { 910 void _connectionEstablished(Socket socket) {
928 _socket = socket; 911 _socket = socket;
929 // Register handler for socket events. 912 // Register handler for socket events.
930 _socket.dataHandler = _dataHandler; 913 _socket.dataHandler = _dataHandler;
931 _socket.closeHandler = _closeHandler; 914 _socket.closeHandler = _closeHandler;
932 _socket.errorHandler = _errorHandler; 915 _socket.errorHandler = _errorHandler;
933 } 916 }
934 917
935 OutputStream get outputStream() { 918 OutputStream get outputStream() {
936 if (_socket == null) throw new HTTPException("Connection closed");
937 return _socket.outputStream; 919 return _socket.outputStream;
938 } 920 }
939 921
940 void _dataHandler() { 922 void _dataHandler() {
941 int available = _socket.available(); 923 int available = _socket.available();
942 if (available == 0) { 924 if (available == 0) {
943 return; 925 return;
944 } 926 }
945 927
946 ByteArray buffer = new ByteArray(available); 928 ByteArray buffer = new ByteArray(available);
947 int bytesRead = _socket.readList(buffer, 0, available); 929 int bytesRead = _socket.readList(buffer, 0, available);
948 if (bytesRead > 0) { 930 if (bytesRead > 0) {
949 int parsed = _httpParser.writeList(buffer, 0, bytesRead); 931 int parsed = _httpParser.writeList(buffer, 0, bytesRead);
950 if (parsed != bytesRead) { 932 if (parsed != bytesRead) {
951 print("Failed to parse HTTP data $parsed $bytesRead"); 933 print("Failed to parse HTTP data $parsed $bytesRead");
952 _socket.close(); 934 _socket.close();
953 } 935 }
954 } 936 }
955 } 937 }
956 938
957 void _closeHandler() { 939 void _closeHandler() {
958 _socket.close(); 940 // Client closed socket for writing. Socket should still be open
959 // Set to null to avoid further write attempts. 941 // for writing the response.
960 _socket = null; 942 _closing = true;
961 if (_disconnectHandlerCallback != null) _disconnectHandlerCallback(); 943 if (_disconnectHandlerCallback != null) _disconnectHandlerCallback();
962 } 944 }
963 945
964 void _errorHandler() { 946 void _errorHandler() {
965 // If an error occours, treat the socket as closed. 947 // If an error occours, treat the socket as closed.
966 _closeHandler(); 948 _closeHandler();
967 if (_errorHandlerCallback != null) { 949 if (_errorHandlerCallback != null) {
968 _errorHandlerCallback("Connection closed while sending data to client."); 950 _errorHandlerCallback("Connection closed while sending data to client.");
969 } 951 }
970 } 952 }
971 953
972 void set disconnectHandler(void callback()) { 954 void set disconnectHandler(void callback()) {
973 _disconnectHandlerCallback = callback; 955 _disconnectHandlerCallback = callback;
974 } 956 }
975 957
976 void set errorHandler(void callback(String errorMessage)) { 958 void set errorHandler(void callback(String errorMessage)) {
977 _errorHandlerCallback = callback; 959 _errorHandlerCallback = callback;
978 } 960 }
979 961
980 Socket _socket; 962 Socket _socket;
963 bool _closing = false; // Is the socket closed by the client?
981 HTTPParser _httpParser; 964 HTTPParser _httpParser;
982 965
983 Queue _sendBuffers; 966 Queue _sendBuffers;
984 967
985 Function _disconnectHandlerCallback; 968 Function _disconnectHandlerCallback;
986 Function _errorHandlerCallback; 969 Function _errorHandlerCallback;
987 } 970 }
988 971
989 972
990 // HTTP server connection over a socket. 973 // HTTP server connection over a socket.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 1078
1096 ServerSocket _server; // The server listen socket. 1079 ServerSocket _server; // The server listen socket.
1097 List<_HTTPConnection> _connections; // List of currently connected clients. 1080 List<_HTTPConnection> _connections; // List of currently connected clients.
1098 Function _requestHandler; 1081 Function _requestHandler;
1099 Function _errorHandler; 1082 Function _errorHandler;
1100 bool _debugTrace; 1083 bool _debugTrace;
1101 } 1084 }
1102 1085
1103 1086
1104 class _HTTPClientRequest 1087 class _HTTPClientRequest
1105 extends _HTTPRequestOrResponse implements HTTPClientRequest { 1088 extends _HTTPRequestResponseBase implements HTTPClientRequest {
1106 static final int START = 0; 1089 static final int START = 0;
1107 static final int HEADERS_SENT = 1; 1090 static final int HEADERS_SENT = 1;
1108 static final int DONE = 2; 1091 static final int DONE = 2;
1109 1092
1110 _HTTPClientRequest(String this._method, 1093 _HTTPClientRequest(String this._method,
1111 String this._uri, 1094 String this._uri,
1112 _HTTPClientConnection connection) 1095 _HTTPClientConnection connection)
1113 : super(connection), 1096 : super(connection),
1114 _state = START { 1097 _state = START {
1115 _connection = connection; 1098 _connection = connection;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 */ 1134 */
1152 void _streamWrite(List<int> buffer, bool copyBuffer) { 1135 void _streamWrite(List<int> buffer, bool copyBuffer) {
1153 _write(buffer, copyBuffer); 1136 _write(buffer, copyBuffer);
1154 } 1137 }
1155 1138
1156 void _streamWriteFrom(List<int> buffer, int offset, int len) { 1139 void _streamWriteFrom(List<int> buffer, int offset, int len) {
1157 _writeList(buffer, offset, len); 1140 _writeList(buffer, offset, len);
1158 } 1141 }
1159 1142
1160 void _streamClose() { 1143 void _streamClose() {
1144 _state = DONE;
1145 // Stop tracking no pending write events.
1146 _httpConnection.outputStream.noPendingWriteHandler = null;
1161 // Ensure that any trailing data is written. 1147 // Ensure that any trailing data is written.
1162 _writeDone(); 1148 _writeDone();
1163 _state = DONE; 1149 // If the connection is closing then close the output stream to
1150 // fully close the socket.
1151 if (_httpConnection._closing) {
1152 _httpConnection.outputStream.close();
1153 }
1164 } 1154 }
1165 1155
1166 void _streamSetNoPendingWriteHandler(callback()) { 1156 void _streamSetNoPendingWriteHandler(callback()) {
1167 _httpConnection.outputStream.noPendingWriteHandler = callback; 1157 if (_state != DONE) {
1158 _httpConnection.outputStream.noPendingWriteHandler = callback;
1159 }
1168 } 1160 }
1169 1161
1170 void _streamSetCloseHandler(callback()) { 1162 void _streamSetCloseHandler(callback()) {
1171 // TODO(sgjesse): Handle this. 1163 // TODO(sgjesse): Handle this.
1172 } 1164 }
1173 1165
1174 void _streamSetErrorHandler(callback()) { 1166 void _streamSetErrorHandler(callback()) {
1175 // TODO(sgjesse): Handle this. 1167 // TODO(sgjesse): Handle this.
1176 } 1168 }
1177 1169
(...skipping 29 matching lines...) Expand all
1207 1199
1208 String _method; 1200 String _method;
1209 String _uri; 1201 String _uri;
1210 _HTTPClientConnection _connection; 1202 _HTTPClientConnection _connection;
1211 _HTTPOutputStream _outputStream; 1203 _HTTPOutputStream _outputStream;
1212 int _state; 1204 int _state;
1213 } 1205 }
1214 1206
1215 1207
1216 class _HTTPClientResponse 1208 class _HTTPClientResponse
1217 extends _HTTPRequestOrResponse implements HTTPClientResponse { 1209 extends _HTTPRequestResponseBase implements HTTPClientResponse {
1218 _HTTPClientResponse(_HTTPClientConnection connection) 1210 _HTTPClientResponse(_HTTPClientConnection connection)
1219 : super(connection) { 1211 : super(connection) {
1220 _connection = connection; 1212 _connection = connection;
1221 } 1213 }
1222 1214
1223 int get statusCode() { return _statusCode; } 1215 int get statusCode() { return _statusCode; }
1224 int get reasonPhrase() { return _reasonPhrase; } 1216 int get reasonPhrase() { return _reasonPhrase; }
1225 Map get headers() => _headers; 1217 Map get headers() => _headers;
1226 1218
1219 InputStream get inputStream() {
1220 if (_inputStream == null) {
1221 _inputStream = new _HTTPInputStream(this);
1222 }
1223 return _inputStream;
1224 }
1225
1227 void _requestStartHandler(String method, String uri) { 1226 void _requestStartHandler(String method, String uri) {
1228 // TODO(sgjesse): Error handling 1227 // TODO(sgjesse): Error handling
1229 } 1228 }
1230 1229
1231 void _responseStartHandler(int statusCode, String reasonPhrase) { 1230 void _responseStartHandler(int statusCode, String reasonPhrase) {
1232 _statusCode = statusCode; 1231 _statusCode = statusCode;
1233 _reasonPhrase = reasonPhrase; 1232 _reasonPhrase = reasonPhrase;
1234 } 1233 }
1235 1234
1236 void _headerReceivedHandler(String name, String value) { 1235 void _headerReceivedHandler(String name, String value) {
1237 _setHeader(name, value); 1236 _setHeader(name, value);
1238 } 1237 }
1239 1238
1240 void _headersCompleteHandler() { 1239 void _headersCompleteHandler() {
1240 _buffer = new _BufferList();
1241 if (_connection._responseHandler != null) { 1241 if (_connection._responseHandler != null) {
1242 _connection._responseHandler(this); 1242 _connection._responseHandler(this);
1243 } 1243 }
1244 } 1244 }
1245 1245
1246 void _dataReceivedHandler(List<int> data) {
1247 _buffer.add(data);
1248 if (_inputStream != null) _inputStream._dataReceived();
1249 }
1250
1251 void _dataEndHandler() {
1252 if (_inputStream != null) _inputStream._closeReceived();
1253 }
1254
1255 /*
1256 * Delegate functions for the HTTPInputStream implementation.
Mads Ager (google) 2012/02/28 12:27:40 Maybe just use '//' comment.
Søren Gjesse 2012/02/28 13:03:42 Done.
1257 */
1258 int _streamAvailable() {
1259 return _buffer.length;
1260 }
1261
1262 List<int> _streamRead(int bytesToRead) {
1263 return _buffer.readBytes(bytesToRead);
1264 }
1265
1266 int _streamReadInto(List<int> buffer, int offset, int len) {
1267 List<int> data = _buffer.readBytes(len);
1268 buffer.setRange(offset, data.length, data);
1269 return data.length;
1270 }
1271
1246 int _statusCode; 1272 int _statusCode;
1247 String _reasonPhrase; 1273 String _reasonPhrase;
1248 1274
1249 _HTTPClientConnection _connection; 1275 _HTTPClientConnection _connection;
1250 var _responseReceived; 1276 _HTTPInputStream _inputStream;
1277 _BufferList _buffer;
1251 } 1278 }
1252 1279
1253 1280
1254 class _HTTPClientConnection 1281 class _HTTPClientConnection
1255 extends _HTTPConnectionBase implements HTTPClientConnection { 1282 extends _HTTPConnectionBase implements HTTPClientConnection {
1256 _HTTPClientConnection(_HTTPClient this._client); 1283 _HTTPClientConnection(_HTTPClient this._client);
1257 1284
1258 void _connectionEstablished(_SocketConnection socketConn) { 1285 void _connectionEstablished(_SocketConnection socketConn) {
1259 super._connectionEstablished(socketConn._socket); 1286 super._connectionEstablished(socketConn._socket);
1260 _socketConn = socketConn; 1287 _socketConn = socketConn;
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 } else { 1571 } else {
1545 value = queryString.substring(currentPosition, position); 1572 value = queryString.substring(currentPosition, position);
1546 currentPosition = position + 1; 1573 currentPosition = position + 1;
1547 } 1574 }
1548 result[HTTPUtil.decodeUrlEncodedString(name)] = 1575 result[HTTPUtil.decodeUrlEncodedString(name)] =
1549 HTTPUtil.decodeUrlEncodedString(value); 1576 HTTPUtil.decodeUrlEncodedString(value);
1550 } 1577 }
1551 return result; 1578 return result;
1552 } 1579 }
1553 } 1580 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698