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

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

Issue 9834008: Add error handling to the HTTP library (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 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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698