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

Side by Side Diff: runtime/bin/http_impl.dart

Issue 9956062: Refactor the close and error handling of HTTP connections (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed additional review comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/bin/http_parser.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (_outputStream == null) { 253 if (_outputStream == null) {
254 // Ensure that headers are written. 254 // Ensure that headers are written.
255 if (_state == START) { 255 if (_state == START) {
256 _writeHeader(); 256 _writeHeader();
257 } 257 }
258 _outputStream = new _HttpOutputStream(this); 258 _outputStream = new _HttpOutputStream(this);
259 } 259 }
260 return _outputStream; 260 return _outputStream;
261 } 261 }
262 262
263 void _responseEnd() {
264 _state = DONE;
265 // Stop tracking no pending write events.
266 _httpConnection.outputStream.onNoPendingWrites = null;
267 // Ensure that any trailing data is written.
268 _writeDone();
269 // Indicate to the connection that the response handling is done.
270 _httpConnection._responseDone();
271 }
272
263 // Delegate functions for the HttpOutputStream implementation. 273 // Delegate functions for the HttpOutputStream implementation.
264 bool _streamWrite(List<int> buffer, bool copyBuffer) { 274 bool _streamWrite(List<int> buffer, bool copyBuffer) {
265 return _write(buffer, copyBuffer); 275 return _write(buffer, copyBuffer);
266 } 276 }
267 277
268 bool _streamWriteFrom(List<int> buffer, int offset, int len) { 278 bool _streamWriteFrom(List<int> buffer, int offset, int len) {
269 return _writeList(buffer, offset, len); 279 return _writeList(buffer, offset, len);
270 } 280 }
271 281
272 void _streamClose() { 282 void _streamClose() {
273 _httpConnection._phase = _HttpConnectionBase.PHASE_IDLE; 283 _responseEnd();
274 _state = DONE;
275 // Stop tracking no pending write events.
276 _httpConnection._onNoPendingWrites = null;
277 // Ensure that any trailing data is written.
278 _writeDone();
279 // If the connection is closing then close the output stream to
280 // fully close the socket.
281 if (_httpConnection._closing) {
282 _httpConnection._close();
283 }
284 } 284 }
285 285
286 void _streamSetNoPendingWriteHandler(callback()) { 286 void _streamSetNoPendingWriteHandler(callback()) {
287 if (_state != DONE) { 287 if (_state != DONE) {
288 _httpConnection._onNoPendingWrites = callback; 288 _httpConnection._onNoPendingWrites = callback;
289 } 289 }
290 } 290 }
291 291
292 void _streamSetCloseHandler(callback()) { 292 void _streamSetCloseHandler(callback()) {
293 // TODO(sgjesse): Handle this. 293 // TODO(sgjesse): Handle this.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 462
463 void set onError(void callback(Exception e)) { 463 void set onError(void callback(Exception e)) {
464 _requestOrResponse._streamSetErrorHandler(callback); 464 _requestOrResponse._streamSetErrorHandler(callback);
465 } 465 }
466 466
467 _HttpRequestResponseBase _requestOrResponse; 467 _HttpRequestResponseBase _requestOrResponse;
468 } 468 }
469 469
470 470
471 class _HttpConnectionBase implements Hashable { 471 class _HttpConnectionBase implements Hashable {
472 static final int PHASE_IDLE = 0; 472 _HttpConnectionBase() : _sendBuffers = new Queue(),
473 static final int PHASE_REQUEST = 1;
474 static final int PHASE_RESPONSE = 2;
475
476 _HttpConnectionBase() : _phase = PHASE_IDLE,
477 _sendBuffers = new Queue(),
478 _httpParser = new _HttpParser(); 473 _httpParser = new _HttpParser();
479 474
480 void _connectionEstablished(Socket socket) { 475 void _connectionEstablished(Socket socket) {
481 _socket = socket; 476 _socket = socket;
482 // Register handler for socket events. 477 // Register handler for socket events.
483 _socket.onData = _onData; 478 _socket.onData = _onData;
484 _socket.onClosed = _onClosed; 479 _socket.onClosed = _onClosed;
485 _socket.onError = _onError; 480 _socket.onError = _onError;
486 } 481 }
487 482
488 bool _write(List<int> data, [bool copyBuffer = false]) { 483 bool _write(List<int> data, [bool copyBuffer = false]) {
489 if (!_error) { 484 if (!_error) {
Anders Johnsen 2012/04/10 08:18:53 I think we should add "&& !_closing".
490 return _socket.outputStream.write(data, copyBuffer); 485 return _socket.outputStream.write(data, copyBuffer);
491 } 486 }
492 } 487 }
493 488
494 bool _writeFrom(List<int> buffer, [int offset, int len]) { 489 bool _writeFrom(List<int> buffer, [int offset, int len]) {
495 if (!_error) { 490 if (!_error) {
Anders Johnsen 2012/04/10 08:18:53 Same here.
496 return _socket.outputStream.writeFrom(buffer, offset, len); 491 return _socket.outputStream.writeFrom(buffer, offset, len);
497 } 492 }
498 } 493 }
499 494
500 bool _close() { 495 bool _close() {
501 _socket.close(); 496 _socket.close();
502 } 497 }
503 498
504 void _onData() { 499 void _onData() {
505 int available = _socket.available(); 500 int available = _socket.available();
506 if (available == 0) { 501 if (available == 0) {
507 return; 502 return;
508 } 503 }
509 504
510 ByteArray buffer = new ByteArray(available); 505 ByteArray buffer = new ByteArray(available);
511 int bytesRead = _socket.readList(buffer, 0, available); 506 int bytesRead = _socket.readList(buffer, 0, available);
512 if (bytesRead > 0) { 507 if (bytesRead > 0) {
513 int parsed = _httpParser.writeList(buffer, 0, bytesRead); 508 int parsed = _httpParser.writeList(buffer, 0, bytesRead);
514 if (parsed != bytesRead) { 509 if (parsed != bytesRead) {
515 // TODO(sgjesse): Error handling. 510 // TODO(sgjesse): Error handling.
516 _socket.close(); 511 _socket.close();
517 } 512 }
518 } 513 }
519 } 514 }
520 515
521 void _onClosed() { 516 void _onClosed() {
Anders Johnsen 2012/04/10 08:18:53 And a "_closing = true;" here.
522 if (_phase != PHASE_IDLE) { 517 _onConnectionClosed(null);
523 // Client closed socket for writing. Socket should still be open
524 // for writing the response.
525 _closing = true;
526 } else {
527 // The connection is currently not used by any request just close it.
528 _socket.close();
529 }
530 if (_onDisconnectCallback != null) _onDisconnectCallback();
531 } 518 }
532 519
533 void _onError(Exception e) { 520 void _onError(Exception e) {
534 // If an error occurs, make sure to close the socket if one is associated. 521 // If an error occurs, make sure to close the socket if one is associated.
535 _error = true; 522 _error = true;
536 if (_socket != null) { 523 if (_socket != null) {
537 _socket.close(); 524 _socket.close();
538 } 525 }
539 if (_onErrorCallback != null) { 526 _onConnectionClosed(e);
540 _onErrorCallback(e);
541 }
542 _propagateError(e);
543 } 527 }
544 528
545 abstract void _propagateError(Exception e); 529 abstract void _onConnectionClosed(Exception e);
546 530 abstract void _responseDone();
547 void set onDisconnect(void callback()) {
548 _onDisconnectCallback = callback;
549 }
550
551 void set onError(void callback(Exception e)) {
552 _onErrorCallback = callback;
553 }
554 531
555 void set _onNoPendingWrites(void callback()) { 532 void set _onNoPendingWrites(void callback()) {
556 if (!_error) { 533 if (!_error) {
557 _socket.outputStream.onNoPendingWrites = callback; 534 _socket.outputStream.onNoPendingWrites = callback;
558 } 535 }
559 } 536 }
560 537
561 int hashCode() => _socket.hashCode(); 538 int hashCode() => _socket.hashCode();
562 539
563 int _phase;
564 Socket _socket; 540 Socket _socket;
565 bool _closing = false; // Is the socket closed by the client? 541 bool _closing = false; // Is the socket closed by the client?
566 bool _error = false; // Is the socket closed due to an error? 542 bool _error = false; // Is the socket closed due to an error?
567 _HttpParser _httpParser; 543 _HttpParser _httpParser;
568 544
569 Queue _sendBuffers; 545 Queue _sendBuffers;
570
571 Function _onDisconnectCallback;
572 Function _onErrorCallback;
573 } 546 }
574 547
575 548
576 // HTTP server connection over a socket. 549 // HTTP server connection over a socket.
577 class _HttpConnection extends _HttpConnectionBase { 550 class _HttpConnection extends _HttpConnectionBase {
578 _HttpConnection(HttpServer this._server) { 551 _HttpConnection(HttpServer this._server) {
579 // Register HTTP parser callbacks. 552 // Register HTTP parser callbacks.
580 _httpParser.requestStart = 553 _httpParser.requestStart =
581 (method, uri) => _onRequestStart(method, uri); 554 (method, uri) => _onRequestStart(method, uri);
582 _httpParser.responseStart = 555 _httpParser.responseStart =
583 (statusCode, reasonPhrase) => 556 (statusCode, reasonPhrase) =>
584 _onResponseStart(statusCode, reasonPhrase); 557 _onResponseStart(statusCode, reasonPhrase);
585 _httpParser.headerReceived = 558 _httpParser.headerReceived =
586 (name, value) => _onHeaderReceived(name, value); 559 (name, value) => _onHeaderReceived(name, value);
587 _httpParser.headersComplete = () => _onHeadersComplete(); 560 _httpParser.headersComplete = () => _onHeadersComplete();
588 _httpParser.dataReceived = (data) => _onDataReceived(data); 561 _httpParser.dataReceived = (data) => _onDataReceived(data);
589 _httpParser.dataEnd = () => _onDataEnd(); 562 _httpParser.dataEnd = (close) => _onDataEnd(close);
590 _httpParser.error = (e) => _onError(e); 563 _httpParser.error = (e) => _onError(e);
591 } 564 }
592 565
566 void _onConnectionClosed(Exception e) {
567 if (e != null && onError != null) {
568 onError(e);
569 // Propagate the error to the streams.
570 if (_request != null && _request._streamErrorHandler != null) {
571 _request._streamErrorHandler(e);
572 }
573 if (_response != null && _response._streamErrorHandler != null) {
574 _response._streamErrorHandler(e);
575 }
576 }
577
578 // If currently not processing any request just close the socket.
579 if (_httpParser.isIdle) {
580 _socket.close();
581 if (onClosed != null && e == null) {
582 // Don't call onClosed if onError has been called.
583 onClosed();
584 }
585 return;
586 }
587
588 // Processing a request.
589 if (e == null) {
590 // Indicate connection close to the HTTP parser.
591 _httpParser.connectionClosed();
592 _closing = true;
Anders Johnsen 2012/04/10 08:18:53 And remove it here, since we mark it in super clas
593 }
594 }
595
593 void _onRequestStart(String method, String uri) { 596 void _onRequestStart(String method, String uri) {
594 // Create new request and response objects for this request. 597 // Create new request and response objects for this request.
595 _phase = PHASE_REQUEST;
596 _request = new _HttpRequest(this); 598 _request = new _HttpRequest(this);
597 _response = new _HttpResponse(this); 599 _response = new _HttpResponse(this);
598 _request._onRequestStart(method, uri); 600 _request._onRequestStart(method, uri);
599 } 601 }
600 602
601 void _onResponseStart(int statusCode, String reasonPhrase) { 603 void _onResponseStart(int statusCode, String reasonPhrase) {
602 // TODO(sgjesse): Error handling. 604 // TODO(sgjesse): Error handling.
603 } 605 }
604 606
605 void _onHeaderReceived(String name, String value) { 607 void _onHeaderReceived(String name, String value) {
606 _request._onHeaderReceived(name, value); 608 _request._onHeaderReceived(name, value);
607 } 609 }
608 610
609 void _onHeadersComplete() { 611 void _onHeadersComplete() {
610 _request._onHeadersComplete(); 612 _request._onHeadersComplete();
611 _response.keepAlive = _httpParser.keepAlive; 613 _response.keepAlive = _httpParser.keepAlive;
612 if (requestReceived != null) { 614 if (onRequestReceived != null) {
613 requestReceived(_request, _response); 615 onRequestReceived(_request, _response);
614 } 616 }
615 } 617 }
616 618
617 void _onDataReceived(List<int> data) { 619 void _onDataReceived(List<int> data) {
618 _request._onDataReceived(data); 620 _request._onDataReceived(data);
619 } 621 }
620 622
621 void _onDataEnd() { 623 void _onDataEnd(bool close) {
622 // Phase might already have gone to PHASE_IDLE if the response is 624 if (_request != null) {
623 // sent without waiting for request body. 625 _request._onDataEnd();
624 if (_phase == PHASE_REQUEST) {
625 _phase = PHASE_RESPONSE;
626 } 626 }
627 _request._onDataEnd(); 627 _request = null;
628 } 628 }
629 629
630 void _propagateError(Exception e) { 630 void _responseDone() {
631 if (_request != null && _request._streamErrorHandler != null) { 631 // If the connection is closing then close the output stream to
632 _request._streamErrorHandler(e); 632 // fully close the socket.
633 if (_closing) {
634 outputStream.close();
633 } 635 }
634 if (_response != null && _response._streamErrorHandler != null) { 636 _response = null;
635 _response._streamErrorHandler(e);
636 }
637 } 637 }
638 638
639 HttpServer _server; 639 HttpServer _server;
640 HttpRequest _request; 640 HttpRequest _request;
641 HttpResponse _response; 641 HttpResponse _response;
642 642
643 // Callbacks. 643 // Callbacks.
644 var requestReceived; 644 Function onRequestReceived;
645 Function onClosed;
646 Function onError;
645 } 647 }
646 648
647 649
648 // HTTP server waiting for socket connections. The connections are 650 // HTTP server waiting for socket connections. The connections are
649 // managed by the server and as requests are received the request. 651 // managed by the server and as requests are received the request.
650 class _HttpServer implements HttpServer { 652 class _HttpServer implements HttpServer {
651 _HttpServer() : _connections = new Set<_HttpConnection>(); 653 _HttpServer() : _connections = new Set<_HttpConnection>();
652 654
653 void listen(String host, int port, [int backlog = 5]) { 655 void listen(String host, int port, [int backlog = 5]) {
654 listenOn(new ServerSocket(host, port, backlog)); 656 listenOn(new ServerSocket(host, port, backlog));
655 _closeServer = true; 657 _closeServer = true;
656 } 658 }
657 659
658 void listenOn(ServerSocket serverSocket) { 660 void listenOn(ServerSocket serverSocket) {
659 void onConnection(Socket socket) { 661 void onConnection(Socket socket) {
660 // Accept the client connection. 662 // Accept the client connection.
661 _HttpConnection connection = new _HttpConnection(this); 663 _HttpConnection connection = new _HttpConnection(this);
662 connection.requestReceived = _onRequest; 664 connection._connectionEstablished(socket);
663 connection.onDisconnect = () => _connections.remove(connection); 665 connection.onRequestReceived = _onRequest;
666 connection.onClosed = () => _connections.remove(connection);
664 connection.onError = (e) { 667 connection.onError = (e) {
668 _connections.remove(connection);
665 if (_onError != null) _onError(e); 669 if (_onError != null) _onError(e);
666 }; 670 };
667 connection._connectionEstablished(socket); 671 connection._connectionEstablished(socket);
668 _connections.add(connection); 672 _connections.add(connection);
669 } 673 }
670 serverSocket.onConnection = onConnection; 674 serverSocket.onConnection = onConnection;
671 _server = serverSocket; 675 _server = serverSocket;
672 _closeServer = false; 676 _closeServer = false;
673 } 677 }
674 678
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 bool _streamWriteFrom(List<int> buffer, int offset, int len) { 789 bool _streamWriteFrom(List<int> buffer, int offset, int len) {
786 return _writeList(buffer, offset, len); 790 return _writeList(buffer, offset, len);
787 } 791 }
788 792
789 void _streamClose() { 793 void _streamClose() {
790 _state = DONE; 794 _state = DONE;
791 // Stop tracking no pending write events. 795 // Stop tracking no pending write events.
792 _httpConnection._onNoPendingWrites = null; 796 _httpConnection._onNoPendingWrites = null;
793 // Ensure that any trailing data is written. 797 // Ensure that any trailing data is written.
794 _writeDone(); 798 _writeDone();
795 // If the connection is closing then close the output stream to
796 // fully close the socket.
797 if (_httpConnection._closing) {
798 _httpConnection._close();
799 }
800 } 799 }
801 800
802 void _streamSetNoPendingWriteHandler(callback()) { 801 void _streamSetNoPendingWriteHandler(callback()) {
803 if (_state != DONE) { 802 if (_state != DONE) {
804 _httpConnection._onNoPendingWrites = callback; 803 _httpConnection._onNoPendingWrites = callback;
805 } 804 }
806 } 805 }
807 806
808 void _streamSetCloseHandler(callback()) { 807 void _streamSetCloseHandler(callback()) {
809 // TODO(sgjesse): Handle this. 808 // TODO(sgjesse): Handle this.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 } 897 }
899 } 898 }
900 899
901 void _onDataReceived(List<int> data) { 900 void _onDataReceived(List<int> data) {
902 _buffer.add(data); 901 _buffer.add(data);
903 if (_inputStream != null) _inputStream._dataReceived(); 902 if (_inputStream != null) _inputStream._dataReceived();
904 } 903 }
905 904
906 void _onDataEnd() { 905 void _onDataEnd() {
907 if (_inputStream != null) _inputStream._closeReceived(); 906 if (_inputStream != null) _inputStream._closeReceived();
907 _connection._responseDone();
908 } 908 }
909 909
910 // Delegate functions for the HttpInputStream implementation. 910 // Delegate functions for the HttpInputStream implementation.
911 int _streamAvailable() { 911 int _streamAvailable() {
912 return _buffer.length; 912 return _buffer.length;
913 } 913 }
914 914
915 List<int> _streamRead(int bytesToRead) { 915 List<int> _streamRead(int bytesToRead) {
916 return _buffer.readBytes(bytesToRead); 916 return _buffer.readBytes(bytesToRead);
917 } 917 }
(...skipping 28 matching lines...) Expand all
946 // Register HTTP parser callbacks. 946 // Register HTTP parser callbacks.
947 _httpParser.requestStart = 947 _httpParser.requestStart =
948 (method, uri) => _onRequestStart(method, uri); 948 (method, uri) => _onRequestStart(method, uri);
949 _httpParser.responseStart = 949 _httpParser.responseStart =
950 (statusCode, reasonPhrase) => 950 (statusCode, reasonPhrase) =>
951 _onResponseStart(statusCode, reasonPhrase); 951 _onResponseStart(statusCode, reasonPhrase);
952 _httpParser.headerReceived = 952 _httpParser.headerReceived =
953 (name, value) => _onHeaderReceived(name, value); 953 (name, value) => _onHeaderReceived(name, value);
954 _httpParser.headersComplete = () => _onHeadersComplete(); 954 _httpParser.headersComplete = () => _onHeadersComplete();
955 _httpParser.dataReceived = (data) => _onDataReceived(data); 955 _httpParser.dataReceived = (data) => _onDataReceived(data);
956 _httpParser.dataEnd = () => _onDataEnd(); 956 _httpParser.dataEnd = (closed) => _onDataEnd(closed);
957 _httpParser.error = (e) => _onError(e); 957 _httpParser.error = (e) => _onError(e);
958 // Tell the HTTP parser the method it is expecting a response to. 958 // Tell the HTTP parser the method it is expecting a response to.
959 _httpParser.responseToMethod = _method; 959 _httpParser.responseToMethod = _method;
960
961 onDisconnect = _onDisconnected;
962 } 960 }
963 961
964 void _propagateError(Exception e) { 962 void _responseDone() {
965 if (_response != null && _response._streamErrorHandler != null) { 963 if (_closing) {
966 _response._streamErrorHandler(e); 964 if (_socket != null) {
965 _socket.close();
966 }
967 } else {
968 _client._returnSocketConnection(_socketConn);
967 } 969 }
970 _socket = null;
971 _socketConn = null;
968 } 972 }
969 973
970 HttpClientRequest open(String method, String uri) { 974 HttpClientRequest open(String method, String uri) {
971 _method = method; 975 _method = method;
972 _request = new _HttpClientRequest(method, uri, this); 976 _request = new _HttpClientRequest(method, uri, this);
973 _request.keepAlive = true; 977 _request.keepAlive = true;
974 _response = new _HttpClientResponse(this); 978 _response = new _HttpClientResponse(this);
975 return _request; 979 return _request;
976 } 980 }
977 981
982 void _onConnectionClosed(Exception e) {
983 // Socket is closed either due to an error or due to normal socket close.
984 if (e != null) {
985 if (_onErrorCallback != null) {
986 _onErrorCallback(e);
987 }
988 }
989 _closing = true;
990 if (e != null) {
991 // Propagate the error to the streams.
992 if (_response != null && _response._streamErrorHandler != null) {
993 _response._streamErrorHandler(e);
994 }
995 _responseDone();
996 } else {
997 // If there was no socket error the socket was closed
998 // normally. Indicate closing to the HTTP Parser as there might
999 // still be an HTTP error.
1000 _httpParser.connectionClosed();
1001 }
1002 }
1003
978 void _onRequestStart(String method, String uri) { 1004 void _onRequestStart(String method, String uri) {
979 // TODO(sgjesse): Error handling. 1005 // TODO(sgjesse): Error handling.
980 } 1006 }
981 1007
982 void _onResponseStart(int statusCode, String reasonPhrase) { 1008 void _onResponseStart(int statusCode, String reasonPhrase) {
983 _response._onResponseStart(statusCode, reasonPhrase); 1009 _response._onResponseStart(statusCode, reasonPhrase);
984 } 1010 }
985 1011
986 void _onHeaderReceived(String name, String value) { 1012 void _onHeaderReceived(String name, String value) {
987 _response._onHeaderReceived(name, value); 1013 _response._onHeaderReceived(name, value);
988 } 1014 }
989 1015
990 void _onHeadersComplete() { 1016 void _onHeadersComplete() {
991 _response._onHeadersComplete(); 1017 _response._onHeadersComplete();
992 } 1018 }
993 1019
994 void _onDataReceived(List<int> data) { 1020 void _onDataReceived(List<int> data) {
995 _response._onDataReceived(data); 1021 _response._onDataReceived(data);
996 } 1022 }
997 1023
998 void _onDataEnd() { 1024 void _onDataEnd(bool close) {
999 onDisconnect = null; 1025 if (close) _closing = true;
1000 if (_response.headers["connection"] == "close") {
1001 _socket.close();
1002 } else {
1003 _client._returnSocketConnection(_socketConn);
1004 }
1005 _socket = null;
1006 _socketConn = null;
1007 _response._onDataEnd(); 1026 _response._onDataEnd();
1008 } 1027 }
1009 1028
1010 void set onRequest(void handler(HttpClientRequest request)) { 1029 void set onRequest(void handler(HttpClientRequest request)) {
1011 _onRequest = handler; 1030 _onRequest = handler;
1012 } 1031 }
1013 1032
1014 void set onResponse(void handler(HttpClientResponse response)) { 1033 void set onResponse(void handler(HttpClientResponse response)) {
1015 _onResponse = handler; 1034 _onResponse = handler;
1016 } 1035 }
1017 1036
1018 void _onDisconnected() { 1037 void set onError(void callback(Exception e)) {
1019 if (_onErrorCallback !== null) { 1038 _onErrorCallback = callback;
1020 _onErrorCallback(new HttpException(
1021 "Client disconnected before response was received."));
1022 }
1023 } 1039 }
1024 1040
1025 Function _onRequest; 1041 Function _onRequest;
1026 Function _onResponse; 1042 Function _onResponse;
1043 Function _onErrorCallback;
1027 1044
1028 _HttpClient _client; 1045 _HttpClient _client;
1029 _SocketConnection _socketConn; 1046 _SocketConnection _socketConn;
1030 HttpClientRequest _request; 1047 HttpClientRequest _request;
1031 HttpClientResponse _response; 1048 HttpClientResponse _response;
1032 String _method; 1049 String _method;
1033 1050
1034 // Callbacks. 1051 // Callbacks.
1035 var requestReceived; 1052 var requestReceived;
1036 } 1053 }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 sockets.addFirst(socketConn); 1244 sockets.addFirst(socketConn);
1228 socketConn._markReturned(); 1245 socketConn._markReturned();
1229 } 1246 }
1230 1247
1231 Function _onOpen; 1248 Function _onOpen;
1232 Map<String, Queue<_SocketConnection>> _openSockets; 1249 Map<String, Queue<_SocketConnection>> _openSockets;
1233 Set<_SocketConnection> _activeSockets; 1250 Set<_SocketConnection> _activeSockets;
1234 Timer _evictionTimer; 1251 Timer _evictionTimer;
1235 bool _shutdown; // Has this HTTP client been shutdown? 1252 bool _shutdown; // Has this HTTP client been shutdown?
1236 } 1253 }
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/http_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698