Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |