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 class _HttpRequestResponseBase { | 5 class _HttpRequestResponseBase { |
| 6 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) | 6 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) |
| 7 : _contentLength = -1, | 7 : _contentLength = -1, |
| 8 _keepAlive = false, | 8 _keepAlive = false, |
| 9 _headers = new Map(); | 9 _headers = new Map(); |
| 10 | 10 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 | 172 |
| 173 List<int> _streamRead(int bytesToRead) { | 173 List<int> _streamRead(int bytesToRead) { |
| 174 return _buffer.readBytes(bytesToRead); | 174 return _buffer.readBytes(bytesToRead); |
| 175 } | 175 } |
| 176 | 176 |
| 177 int _streamReadInto(List<int> buffer, int offset, int len) { | 177 int _streamReadInto(List<int> buffer, int offset, int len) { |
| 178 List<int> data = _buffer.readBytes(len); | 178 List<int> data = _buffer.readBytes(len); |
| 179 buffer.setRange(offset, data.length, data); | 179 buffer.setRange(offset, data.length, data); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void _streamSetErrorHandler(callback(Exception e)) { | |
| 183 _streamErrorHandler = callback | |
| 184 } | |
| 185 | |
| 182 String _method; | 186 String _method; |
| 183 String _uri; | 187 String _uri; |
| 184 String _path; | 188 String _path; |
| 185 String _queryString; | 189 String _queryString; |
| 186 Map<String, String> _queryParameters; | 190 Map<String, String> _queryParameters; |
| 187 _HttpInputStream _inputStream; | 191 _HttpInputStream _inputStream; |
| 188 _BufferList _buffer; | 192 _BufferList _buffer; |
| 193 Function _streamErrorHandler; | |
| 189 } | 194 } |
| 190 | 195 |
| 191 | 196 |
| 192 // HTTP response object for sending a HTTP response. | 197 // HTTP response object for sending a HTTP response. |
| 193 class _HttpResponse extends _HttpRequestResponseBase implements HttpResponse { | 198 class _HttpResponse extends _HttpRequestResponseBase implements HttpResponse { |
| 194 static final int START = 0; | 199 static final int START = 0; |
| 195 static final int HEADERS_SENT = 1; | 200 static final int HEADERS_SENT = 1; |
| 196 static final int DONE = 2; | 201 static final int DONE = 2; |
| 197 | 202 |
| 198 _HttpResponse(_HttpConnection httpConnection) | 203 _HttpResponse(_HttpConnection httpConnection) |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 void _streamSetNoPendingWriteHandler(callback()) { | 286 void _streamSetNoPendingWriteHandler(callback()) { |
| 282 if (_state != DONE) { | 287 if (_state != DONE) { |
| 283 _httpConnection.outputStream.onNoPendingWrites = callback; | 288 _httpConnection.outputStream.onNoPendingWrites = callback; |
| 284 } | 289 } |
| 285 } | 290 } |
| 286 | 291 |
| 287 void _streamSetCloseHandler(callback()) { | 292 void _streamSetCloseHandler(callback()) { |
| 288 // TODO(sgjesse): Handle this. | 293 // TODO(sgjesse): Handle this. |
| 289 } | 294 } |
| 290 | 295 |
| 291 void _streamSetErrorHandler(callback()) { | 296 void _streamSetErrorHandler(callback(Exception e)) { |
| 292 // TODO(sgjesse): Handle this. | 297 _streamErrorHandler = callback |
| 293 } | 298 } |
| 294 | 299 |
| 295 String _findReasonPhrase(int statusCode) { | 300 String _findReasonPhrase(int statusCode) { |
| 296 if (_reasonPhrase != null) { | 301 if (_reasonPhrase != null) { |
| 297 return _reasonPhrase; | 302 return _reasonPhrase; |
| 298 } | 303 } |
| 299 | 304 |
| 300 switch (statusCode) { | 305 switch (statusCode) { |
| 301 case HttpStatus.CONTINUE: return "Continue"; | 306 case HttpStatus.CONTINUE: return "Continue"; |
| 302 case HttpStatus.SWITCHING_PROTOCOLS: return "Switching Protocols"; | 307 case HttpStatus.SWITCHING_PROTOCOLS: return "Switching Protocols"; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 _state = HEADERS_SENT; | 382 _state = HEADERS_SENT; |
| 378 return allWritten; | 383 return allWritten; |
| 379 } | 384 } |
| 380 | 385 |
| 381 // Response status code. | 386 // Response status code. |
| 382 int _statusCode; | 387 int _statusCode; |
| 383 String _reasonPhrase; | 388 String _reasonPhrase; |
| 384 Date _expires; | 389 Date _expires; |
| 385 _HttpOutputStream _outputStream; | 390 _HttpOutputStream _outputStream; |
| 386 int _state; | 391 int _state; |
| 392 Function _streamErrorHandler; | |
| 387 } | 393 } |
| 388 | 394 |
| 389 | 395 |
| 390 class _HttpInputStream extends _BaseDataInputStream implements InputStream { | 396 class _HttpInputStream extends _BaseDataInputStream implements InputStream { |
| 391 _HttpInputStream(_HttpRequestResponseBase this._requestOrResponse) { | 397 _HttpInputStream(_HttpRequestResponseBase this._requestOrResponse) { |
| 392 _checkScheduleCallbacks(); | 398 _checkScheduleCallbacks(); |
| 393 } | 399 } |
| 394 | 400 |
| 395 int available() { | 401 int available() { |
| 396 return _requestOrResponse._streamAvailable(); | 402 return _requestOrResponse._streamAvailable(); |
| 397 } | 403 } |
| 398 | 404 |
| 399 void pipe(OutputStream output, [bool close = true]) { | 405 void pipe(OutputStream output, [bool close = true]) { |
| 400 _pipe(this, output, close: close); | 406 _pipe(this, output, close: close); |
| 401 } | 407 } |
| 402 | 408 |
| 403 List<int> _read(int bytesToRead) { | 409 List<int> _read(int bytesToRead) { |
| 404 List<int> result = _requestOrResponse._streamRead(bytesToRead); | 410 List<int> result = _requestOrResponse._streamRead(bytesToRead); |
| 405 _checkScheduleCallbacks(); | 411 _checkScheduleCallbacks(); |
| 406 return result; | 412 return result; |
| 407 } | 413 } |
| 408 | 414 |
| 415 void set onError(void callback(Exception e)) { | |
| 416 _requestOrResponse._streamSetErrorHandler(callback); | |
| 417 } | |
| 418 | |
| 409 int _readInto(List<int> buffer, int offset, int len) { | 419 int _readInto(List<int> buffer, int offset, int len) { |
| 410 int result = _requestOrResponse._streamReadInto(buffer, offset, len); | 420 int result = _requestOrResponse._streamReadInto(buffer, offset, len); |
| 411 _checkScheduleCallbacks(); | 421 _checkScheduleCallbacks(); |
| 412 return result; | 422 return result; |
| 413 } | 423 } |
| 414 | 424 |
| 415 void _close() { | 425 void _close() { |
| 416 // TODO(sgjesse): Handle this. | 426 // TODO(sgjesse): Handle this. |
| 417 } | 427 } |
| 418 | 428 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 444 } | 454 } |
| 445 | 455 |
| 446 void set onNoPendingWrites(void callback()) { | 456 void set onNoPendingWrites(void callback()) { |
| 447 _requestOrResponse._streamSetNoPendingWriteHandler(callback); | 457 _requestOrResponse._streamSetNoPendingWriteHandler(callback); |
| 448 } | 458 } |
| 449 | 459 |
| 450 void set onClosed(void callback()) { | 460 void set onClosed(void callback()) { |
| 451 _requestOrResponse._streamSetCloseHandler(callback); | 461 _requestOrResponse._streamSetCloseHandler(callback); |
| 452 } | 462 } |
| 453 | 463 |
| 454 void set onError(void callback()) { | 464 void set onError(void callback(Exception e)) { |
| 455 _requestOrResponse._streamSetErrorHandler(callback); | 465 _requestOrResponse._streamSetErrorHandler(callback); |
| 456 } | 466 } |
| 457 | 467 |
| 458 _HttpRequestResponseBase _requestOrResponse; | 468 _HttpRequestResponseBase _requestOrResponse; |
| 459 } | 469 } |
| 460 | 470 |
| 461 | 471 |
| 462 class _HttpConnectionBase implements Hashable { | 472 class _HttpConnectionBase implements Hashable { |
| 463 static final int PHASE_IDLE = 0; | 473 static final int PHASE_IDLE = 0; |
| 464 static final int PHASE_REQUEST = 1; | 474 static final int PHASE_REQUEST = 1; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 // for writing the response. | 513 // for writing the response. |
| 504 _closing = true; | 514 _closing = true; |
| 505 } else { | 515 } else { |
| 506 // The connection is currently not used by any request just close it. | 516 // The connection is currently not used by any request just close it. |
| 507 _socket.close(); | 517 _socket.close(); |
| 508 } | 518 } |
| 509 if (_onDisconnectCallback != null) _onDisconnectCallback(); | 519 if (_onDisconnectCallback != null) _onDisconnectCallback(); |
| 510 } | 520 } |
| 511 | 521 |
| 512 void _onError(Exception e) { | 522 void _onError(Exception e) { |
| 513 // If an error occours, treat the socket as closed. | 523 // If an error occurs, make sure to close the socket if one is associated. |
| 514 _onClosed(); | 524 if (_socket != null) { |
| 525 _socket.close(); | |
| 526 } | |
| 515 if (_onErrorCallback != null) { | 527 if (_onErrorCallback != null) { |
| 516 _onErrorCallback("Connection closed while sending data to client ($e)."); | 528 _onErrorCallback(e); |
| 517 } | 529 } |
| 530 _subOnError(e); | |
|
Mads Ager (google)
2012/03/22 14:30:08
You called this something like _propagateError in
Søren Gjesse
2012/03/23 07:34:20
Done. Sorry for the strange name.
| |
| 518 } | 531 } |
| 519 | 532 |
| 533 abstract void _subOnError(Exception e); | |
| 534 | |
| 520 void set onDisconnect(void callback()) { | 535 void set onDisconnect(void callback()) { |
| 521 _onDisconnectCallback = callback; | 536 _onDisconnectCallback = callback; |
| 522 } | 537 } |
| 523 | 538 |
| 524 void set onError(void callback(String errorMessage)) { | 539 void set onError(void callback(Exception e)) { |
| 525 _onErrorCallback = callback; | 540 _onErrorCallback = callback; |
| 526 } | 541 } |
| 527 | 542 |
| 528 int hashCode() => _socket.hashCode(); | 543 int hashCode() => _socket.hashCode(); |
| 529 | 544 |
| 530 int _phase; | 545 int _phase; |
| 531 Socket _socket; | 546 Socket _socket; |
| 532 bool _closing = false; // Is the socket closed by the client? | 547 bool _closing = false; // Is the socket closed by the client? |
| 533 _HttpParser _httpParser; | 548 _HttpParser _httpParser; |
| 534 | 549 |
| 535 Queue _sendBuffers; | 550 Queue _sendBuffers; |
| 536 | 551 |
| 537 Function _onDisconnectCallback; | 552 Function _onDisconnectCallback; |
| 538 Function _onErrorCallback; | 553 Function _onErrorCallback; |
| 539 } | 554 } |
| 540 | 555 |
| 541 | 556 |
| 542 // HTTP server connection over a socket. | 557 // HTTP server connection over a socket. |
| 543 class _HttpConnection extends _HttpConnectionBase { | 558 class _HttpConnection extends _HttpConnectionBase { |
| 544 _HttpConnection() { | 559 _HttpConnection(HttpServer this._server) { |
| 545 // Register HTTP parser callbacks. | 560 // Register HTTP parser callbacks. |
| 546 _httpParser.requestStart = | 561 _httpParser.requestStart = |
| 547 (method, uri) => _onRequestStart(method, uri); | 562 (method, uri) => _onRequestStart(method, uri); |
| 548 _httpParser.responseStart = | 563 _httpParser.responseStart = |
| 549 (statusCode, reasonPhrase) => | 564 (statusCode, reasonPhrase) => |
| 550 _onResponseStart(statusCode, reasonPhrase); | 565 _onResponseStart(statusCode, reasonPhrase); |
| 551 _httpParser.headerReceived = | 566 _httpParser.headerReceived = |
| 552 (name, value) => _onHeaderReceived(name, value); | 567 (name, value) => _onHeaderReceived(name, value); |
| 553 _httpParser.headersComplete = () => _onHeadersComplete(); | 568 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 554 _httpParser.dataReceived = (data) => _onDataReceived(data); | 569 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 555 _httpParser.dataEnd = () => _onDataEnd(); | 570 _httpParser.dataEnd = () => _onDataEnd(); |
| 571 _httpParser.error = (e) => _onError(e); | |
| 556 } | 572 } |
| 557 | 573 |
| 558 void _onRequestStart(String method, String uri) { | 574 void _onRequestStart(String method, String uri) { |
| 559 // Create new request and response objects for this request. | 575 // Create new request and response objects for this request. |
| 560 _phase = PHASE_REQUEST; | 576 _phase = PHASE_REQUEST; |
| 561 _request = new _HttpRequest(this); | 577 _request = new _HttpRequest(this); |
| 562 _response = new _HttpResponse(this); | 578 _response = new _HttpResponse(this); |
| 563 _request._onRequestStart(method, uri); | 579 _request._onRequestStart(method, uri); |
| 564 } | 580 } |
| 565 | 581 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 585 | 601 |
| 586 void _onDataEnd() { | 602 void _onDataEnd() { |
| 587 // Phase might already have gone to PHASE_IDLE if the response is | 603 // Phase might already have gone to PHASE_IDLE if the response is |
| 588 // sent without waiting for request body. | 604 // sent without waiting for request body. |
| 589 if (_phase == PHASE_REQUEST) { | 605 if (_phase == PHASE_REQUEST) { |
| 590 _phase = PHASE_RESPONSE; | 606 _phase = PHASE_RESPONSE; |
| 591 } | 607 } |
| 592 _request._onDataEnd(); | 608 _request._onDataEnd(); |
| 593 } | 609 } |
| 594 | 610 |
| 611 void _subOnError(Exception e) { | |
| 612 if (_server._onError != null) { | |
| 613 _server._onError(e); | |
| 614 } | |
| 615 if (_request != null && _request._streamErrorHandler != null) { | |
| 616 _request._streamErrorHandler(e); | |
| 617 } | |
| 618 if (_response != null && _response._streamErrorHandler != null) { | |
| 619 _response._streamErrorHandler(e); | |
| 620 } | |
| 621 } | |
| 622 | |
| 623 HttpServer _server; | |
| 595 HttpRequest _request; | 624 HttpRequest _request; |
| 596 HttpResponse _response; | 625 HttpResponse _response; |
| 597 | 626 |
| 598 // Callbacks. | 627 // Callbacks. |
| 599 var requestReceived; | 628 var requestReceived; |
| 600 } | 629 } |
| 601 | 630 |
| 602 | 631 |
| 603 // HTTP server waiting for socket connections. The connections are | 632 // HTTP server waiting for socket connections. The connections are |
| 604 // managed by the server and as requests are received the request. | 633 // managed by the server and as requests are received the request. |
| 605 class _HttpServer implements HttpServer { | 634 class _HttpServer implements HttpServer { |
| 606 void listen(String host, int port, [int backlog = 5]) { | 635 void listen(String host, int port, [int backlog = 5]) { |
| 607 | 636 |
| 608 void onConnection(Socket socket) { | 637 void onConnection(Socket socket) { |
| 609 // Accept the client connection. | 638 // Accept the client connection. |
| 610 _HttpConnection connection = new _HttpConnection(); | 639 _HttpConnection connection = new _HttpConnection(this); |
| 611 connection._connectionEstablished(socket); | 640 connection._connectionEstablished(socket); |
| 612 connection.requestReceived = _onRequest; | 641 connection.requestReceived = _onRequest; |
| 613 _connections.add(connection); | 642 _connections.add(connection); |
| 614 void onDisconnect() { | 643 connection.onDisconnect = () => _connections.remove(connection); |
| 615 _connections.remove(connection); | 644 connection.onError = (e) { |
| 616 } | 645 if (_onError != null) _onError(e); |
| 617 connection.onDisconnect = onDisconnect; | 646 }; |
| 618 void onError(String errorMessage) { | |
| 619 if (_onError != null) _onError(errorMessage); | |
| 620 } | |
| 621 connection.onError = onError; | |
| 622 } | 647 } |
| 623 | 648 |
| 624 _connections = new Set<_HttpConnection>(); | 649 _connections = new Set<_HttpConnection>(); |
| 625 _server = new ServerSocket(host, port, backlog); | 650 _server = new ServerSocket(host, port, backlog); |
| 626 _server.onConnection = onConnection; | 651 _server.onConnection = onConnection; |
| 627 } | 652 } |
| 628 | 653 |
| 629 void close() { | 654 void close() { |
| 630 _server.close(); | 655 _server.close(); |
| 631 for (_HttpConnection connection in _connections) { | 656 for (_HttpConnection connection in _connections) { |
| 632 connection._socket.close(); | 657 connection._socket.close(); |
| 633 } | 658 } |
| 634 } | 659 } |
| 635 | 660 |
| 636 int get port() => _server.port; | 661 int get port() => _server.port; |
| 637 | 662 |
| 638 void set onError(void handler(String errorMessage)) { | 663 void set onError(void callback(Exception e)) { |
| 639 _onError = handler; | 664 _onError = callback; |
| 640 } | 665 } |
| 641 | 666 |
| 642 void set onRequest(void handler(HttpRequest, HttpResponse)) { | 667 void set onRequest(void callback(HttpRequest, HttpResponse)) { |
| 643 _onRequest = handler; | 668 _onRequest = callback; |
| 644 } | 669 } |
| 645 | 670 |
| 646 ServerSocket _server; // The server listen socket. | 671 ServerSocket _server; // The server listen socket. |
| 647 Set<_HttpConnection> _connections; // Set of currently connected clients. | 672 Set<_HttpConnection> _connections; // Set of currently connected clients. |
| 648 Function _onRequest; | 673 Function _onRequest; |
| 649 Function _onError; | 674 Function _onError; |
| 650 } | 675 } |
| 651 | 676 |
| 652 | 677 |
| 653 class _HttpClientRequest | 678 class _HttpClientRequest |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 void _streamSetNoPendingWriteHandler(callback()) { | 771 void _streamSetNoPendingWriteHandler(callback()) { |
| 747 if (_state != DONE) { | 772 if (_state != DONE) { |
| 748 _httpConnection.outputStream.onNoPendingWrites = callback; | 773 _httpConnection.outputStream.onNoPendingWrites = callback; |
| 749 } | 774 } |
| 750 } | 775 } |
| 751 | 776 |
| 752 void _streamSetCloseHandler(callback()) { | 777 void _streamSetCloseHandler(callback()) { |
| 753 // TODO(sgjesse): Handle this. | 778 // TODO(sgjesse): Handle this. |
| 754 } | 779 } |
| 755 | 780 |
| 756 void _streamSetErrorHandler(callback()) { | 781 void _streamSetErrorHandler(callback(Exception e)) { |
| 757 // TODO(sgjesse): Handle this. | 782 _streamErrorHandler = callback; |
| 758 } | 783 } |
| 759 | 784 |
| 760 void _writeHeader() { | 785 void _writeHeader() { |
| 761 List<int> data; | 786 List<int> data; |
| 762 OutputStream stream = _httpConnection.outputStream; | 787 OutputStream stream = _httpConnection.outputStream; |
| 763 | 788 |
| 764 // Write request line. | 789 // Write request line. |
| 765 data = _method.toString().charCodes(); | 790 data = _method.toString().charCodes(); |
| 766 stream.write(data); | 791 stream.write(data); |
| 767 _writeSP(); | 792 _writeSP(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 787 _state = HEADERS_SENT; | 812 _state = HEADERS_SENT; |
| 788 } | 813 } |
| 789 | 814 |
| 790 String _method; | 815 String _method; |
| 791 String _uri; | 816 String _uri; |
| 792 String _host; | 817 String _host; |
| 793 int _port; | 818 int _port; |
| 794 _HttpClientConnection _connection; | 819 _HttpClientConnection _connection; |
| 795 _HttpOutputStream _outputStream; | 820 _HttpOutputStream _outputStream; |
| 796 int _state; | 821 int _state; |
| 822 Function _streamErrorHandler; | |
| 797 } | 823 } |
| 798 | 824 |
| 799 | 825 |
| 800 class _HttpClientResponse | 826 class _HttpClientResponse |
| 801 extends _HttpRequestResponseBase implements HttpClientResponse { | 827 extends _HttpRequestResponseBase implements HttpClientResponse { |
| 802 _HttpClientResponse(_HttpClientConnection connection) | 828 _HttpClientResponse(_HttpClientConnection connection) |
| 803 : super(connection) { | 829 : super(connection) { |
| 804 _connection = connection; | 830 _connection = connection; |
| 805 } | 831 } |
| 806 | 832 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 List<int> _streamRead(int bytesToRead) { | 885 List<int> _streamRead(int bytesToRead) { |
| 860 return _buffer.readBytes(bytesToRead); | 886 return _buffer.readBytes(bytesToRead); |
| 861 } | 887 } |
| 862 | 888 |
| 863 int _streamReadInto(List<int> buffer, int offset, int len) { | 889 int _streamReadInto(List<int> buffer, int offset, int len) { |
| 864 List<int> data = _buffer.readBytes(len); | 890 List<int> data = _buffer.readBytes(len); |
| 865 buffer.setRange(offset, data.length, data); | 891 buffer.setRange(offset, data.length, data); |
| 866 return data.length; | 892 return data.length; |
| 867 } | 893 } |
| 868 | 894 |
| 895 void _streamSetErrorHandler(callback(Exception e)) { | |
| 896 _streamErrorHandler = callback; | |
| 897 } | |
| 898 | |
| 869 int _statusCode; | 899 int _statusCode; |
| 870 String _reasonPhrase; | 900 String _reasonPhrase; |
| 871 | 901 |
| 872 _HttpClientConnection _connection; | 902 _HttpClientConnection _connection; |
| 873 _HttpInputStream _inputStream; | 903 _HttpInputStream _inputStream; |
| 874 _BufferList _buffer; | 904 _BufferList _buffer; |
| 905 Function _streamErrorHandler; | |
| 875 } | 906 } |
| 876 | 907 |
| 877 | 908 |
| 878 class _HttpClientConnection | 909 class _HttpClientConnection |
| 879 extends _HttpConnectionBase implements HttpClientConnection { | 910 extends _HttpConnectionBase implements HttpClientConnection { |
| 880 _HttpClientConnection(_HttpClient this._client); | 911 _HttpClientConnection(_HttpClient this._client); |
| 881 | 912 |
| 882 void _connectionEstablished(_SocketConnection socketConn) { | 913 void _connectionEstablished(_SocketConnection socketConn) { |
| 883 super._connectionEstablished(socketConn._socket); | 914 super._connectionEstablished(socketConn._socket); |
| 884 _socketConn = socketConn; | 915 _socketConn = socketConn; |
| 885 // Register HTTP parser callbacks. | 916 // Register HTTP parser callbacks. |
| 886 _httpParser.requestStart = | 917 _httpParser.requestStart = |
| 887 (method, uri) => _onRequestStart(method, uri); | 918 (method, uri) => _onRequestStart(method, uri); |
| 888 _httpParser.responseStart = | 919 _httpParser.responseStart = |
| 889 (statusCode, reasonPhrase) => | 920 (statusCode, reasonPhrase) => |
| 890 _onResponseStart(statusCode, reasonPhrase); | 921 _onResponseStart(statusCode, reasonPhrase); |
| 891 _httpParser.headerReceived = | 922 _httpParser.headerReceived = |
| 892 (name, value) => _onHeaderReceived(name, value); | 923 (name, value) => _onHeaderReceived(name, value); |
| 893 _httpParser.headersComplete = () => _onHeadersComplete(); | 924 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 894 _httpParser.dataReceived = (data) => _onDataReceived(data); | 925 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 895 _httpParser.dataEnd = () => _onDataEnd(); | 926 _httpParser.dataEnd = () => _onDataEnd(); |
| 927 _httpParser.error = (e) => _onError(e); | |
| 896 // Tell the HTTP parser the method it is expecting a response to. | 928 // Tell the HTTP parser the method it is expecting a response to. |
| 897 _httpParser.responseToMethod = _method; | 929 _httpParser.responseToMethod = _method; |
| 898 | 930 |
| 899 onDisconnect = _onDisconnected; | 931 onDisconnect = _onDisconnected; |
| 900 } | 932 } |
| 901 | 933 |
| 934 void _subOnError(Exception e) { | |
| 935 if (_response._streamErrorHandler != null) { | |
| 936 _response._streamErrorHandler(e); | |
| 937 } | |
| 938 } | |
| 939 | |
| 902 HttpClientRequest open(String method, String uri) { | 940 HttpClientRequest open(String method, String uri) { |
| 903 _method = method; | 941 _method = method; |
| 904 _request = new _HttpClientRequest(method, uri, this); | 942 _request = new _HttpClientRequest(method, uri, this); |
| 905 _request.keepAlive = true; | 943 _request.keepAlive = true; |
| 906 _response = new _HttpClientResponse(this); | 944 _response = new _HttpClientResponse(this); |
| 907 return _request; | 945 return _request; |
| 908 } | 946 } |
| 909 | 947 |
| 910 void _onRequestStart(String method, String uri) { | 948 void _onRequestStart(String method, String uri) { |
| 911 // TODO(sgjesse): Error handling. | 949 // TODO(sgjesse): Error handling. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 926 void _onDataReceived(List<int> data) { | 964 void _onDataReceived(List<int> data) { |
| 927 _response._onDataReceived(data); | 965 _response._onDataReceived(data); |
| 928 } | 966 } |
| 929 | 967 |
| 930 void _onDataEnd() { | 968 void _onDataEnd() { |
| 931 onDisconnect = null; | 969 onDisconnect = null; |
| 932 if (_response.headers["connection"] == "close") { | 970 if (_response.headers["connection"] == "close") { |
| 933 _socket.close(); | 971 _socket.close(); |
| 934 } else { | 972 } else { |
| 935 _client._returnSocketConnection(_socketConn); | 973 _client._returnSocketConnection(_socketConn); |
| 936 _socket = null; | |
| 937 _socketConn = null; | |
| 938 } | 974 } |
| 975 _socket = null; | |
| 976 _socketConn = null; | |
| 939 _response._onDataEnd(); | 977 _response._onDataEnd(); |
| 940 } | 978 } |
| 941 | 979 |
| 942 void set onRequest(void handler(HttpClientRequest request)) { | 980 void set onRequest(void handler(HttpClientRequest request)) { |
| 943 _onRequest = handler; | 981 _onRequest = handler; |
| 944 } | 982 } |
| 945 | 983 |
| 946 void set onResponse(void handler(HttpClientResponse response)) { | 984 void set onResponse(void handler(HttpClientResponse response)) { |
| 947 _onResponse = handler; | 985 _onResponse = handler; |
| 948 } | 986 } |
| 949 | 987 |
| 950 void _onDisconnected() { | 988 void _onDisconnected() { |
| 951 if (_onErrorCallback !== null) { | 989 if (_onErrorCallback !== null) { |
| 952 _onErrorCallback(new HttpException( | 990 _onErrorCallback(new HttpException( |
| 953 "Client disconnected before response was received.")); | 991 "Client disconnected before response was received.")); |
| 954 } | 992 } |
| 955 } | 993 } |
| 956 | 994 |
| 957 | |
| 958 Function _onRequest; | 995 Function _onRequest; |
| 959 Function _onResponse; | 996 Function _onResponse; |
| 960 | 997 |
| 961 _HttpClient _client; | 998 _HttpClient _client; |
| 962 _SocketConnection _socketConn; | 999 _SocketConnection _socketConn; |
| 963 HttpClientRequest _request; | 1000 HttpClientRequest _request; |
| 964 HttpClientResponse _response; | 1001 HttpClientResponse _response; |
| 965 String _method; | 1002 String _method; |
| 966 | 1003 |
| 967 // Callbacks. | 1004 // Callbacks. |
| 968 var requestReceived; | 1005 var requestReceived; |
| 969 | |
| 970 } | 1006 } |
| 971 | 1007 |
| 972 | 1008 |
| 973 // Class for holding keep-alive sockets in the cache for the HTTP | 1009 // Class for holding keep-alive sockets in the cache for the HTTP |
| 974 // client together with the connection information. | 1010 // client together with the connection information. |
| 975 class _SocketConnection { | 1011 class _SocketConnection { |
| 976 _SocketConnection(String this._host, | 1012 _SocketConnection(String this._host, |
| 977 int this._port, | 1013 int this._port, |
| 978 Socket this._socket); | 1014 Socket this._socket); |
| 979 | 1015 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1077 } | 1113 } |
| 1078 } | 1114 } |
| 1079 | 1115 |
| 1080 _HttpClientConnection connection = new _HttpClientConnection(this); | 1116 _HttpClientConnection connection = new _HttpClientConnection(this); |
| 1081 | 1117 |
| 1082 // If there are active connections for this key get the first one | 1118 // If there are active connections for this key get the first one |
| 1083 // otherwise create a new one. | 1119 // otherwise create a new one. |
| 1084 Queue socketConnections = _openSockets[_connectionKey(host, port)]; | 1120 Queue socketConnections = _openSockets[_connectionKey(host, port)]; |
| 1085 if (socketConnections == null || socketConnections.isEmpty()) { | 1121 if (socketConnections == null || socketConnections.isEmpty()) { |
| 1086 Socket socket = new Socket(host, port); | 1122 Socket socket = new Socket(host, port); |
| 1087 socket.onConnect = () { | 1123 socket.onConnect = () { |
|
Mads Ager (google)
2012/03/22 14:30:08
I think it would read better if you move the onErr
Søren Gjesse
2012/03/23 07:34:20
Done.
| |
| 1124 // Clear the error callback as it will now be handled by the | |
|
Mads Ager (google)
2012/03/22 14:30:08
When the connection is established, clear the ...
Søren Gjesse
2012/03/23 07:34:20
Done.
| |
| 1125 // HttpClientConnection object which will be associated with | |
| 1126 // the connected socket. | |
| 1088 socket.onError = null; | 1127 socket.onError = null; |
| 1089 _SocketConnection socketConn = | 1128 _SocketConnection socketConn = |
| 1090 new _SocketConnection(host, port, socket); | 1129 new _SocketConnection(host, port, socket); |
| 1091 _activeSockets.add(socketConn); | 1130 _activeSockets.add(socketConn); |
| 1092 _connectionOpened(socketConn, connection); | 1131 _connectionOpened(socketConn, connection); |
| 1093 }; | 1132 }; |
| 1133 // Until the connection is established handle connection errors | |
| 1134 // here as the HttpClientConnection object is not yet associated | |
| 1135 // with the socket. | |
| 1094 socket.onError = (Exception e) { | 1136 socket.onError = (Exception e) { |
| 1095 if (_onError !== null) { | 1137 // Report the error through the HttpClientConnection object to |
| 1096 _onError(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); | 1138 // the client. |
| 1097 } | 1139 connection._onError(e); |
| 1098 }; | 1140 }; |
| 1099 } else { | 1141 } else { |
| 1100 _SocketConnection socketConn = socketConnections.removeFirst(); | 1142 _SocketConnection socketConn = socketConnections.removeFirst(); |
| 1101 _activeSockets.add(socketConn); | 1143 _activeSockets.add(socketConn); |
| 1102 new Timer(0, (ignored) => _connectionOpened(socketConn, connection)); | 1144 new Timer(0, (ignored) => _connectionOpened(socketConn, connection)); |
| 1103 | 1145 |
| 1104 // Get rid of eviction timer if there are no more active connections. | 1146 // Get rid of eviction timer if there are no more active connections. |
| 1105 if (socketConnections.isEmpty()) { | 1147 if (socketConnections.isEmpty()) { |
| 1106 _evictionTimer.cancel(); | 1148 _evictionTimer.cancel(); |
| 1107 _evictionTimer = null; | 1149 _evictionTimer = null; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1148 } | 1190 } |
| 1149 _evictionTimer = new Timer.repeating(10000, _handleEviction); | 1191 _evictionTimer = new Timer.repeating(10000, _handleEviction); |
| 1150 } | 1192 } |
| 1151 | 1193 |
| 1152 // Return connection. | 1194 // Return connection. |
| 1153 _activeSockets.remove(socketConn); | 1195 _activeSockets.remove(socketConn); |
| 1154 sockets.addFirst(socketConn); | 1196 sockets.addFirst(socketConn); |
| 1155 socketConn._markReturned(); | 1197 socketConn._markReturned(); |
| 1156 } | 1198 } |
| 1157 | 1199 |
| 1158 void set onError(void callback(int status)) { | |
| 1159 _onError = callback; | |
| 1160 } | |
| 1161 | |
| 1162 Function _onOpen; | 1200 Function _onOpen; |
| 1163 Function _onError; | |
| 1164 Map<String, Queue<_SocketConnection>> _openSockets; | 1201 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1165 Set<_SocketConnection> _activeSockets; | 1202 Set<_SocketConnection> _activeSockets; |
| 1166 Timer _evictionTimer; | 1203 Timer _evictionTimer; |
| 1167 bool _shutdown; // Has this HTTP client been shutdown? | 1204 bool _shutdown; // Has this HTTP client been shutdown? |
| 1168 } | 1205 } |
| OLD | NEW |