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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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.outputStream.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.outputStream.close(); | |
| 283 } | |
| 284 } | 284 } |
| 285 | 285 |
| 286 void _streamSetNoPendingWriteHandler(callback()) { | 286 void _streamSetNoPendingWriteHandler(callback()) { |
| 287 if (_state != DONE) { | 287 if (_state != DONE) { |
| 288 _httpConnection.outputStream.onNoPendingWrites = callback; | 288 _httpConnection.outputStream.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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 463 | 463 |
| 464 void set onError(void callback(Exception e)) { | 464 void set onError(void callback(Exception e)) { |
| 465 _requestOrResponse._streamSetErrorHandler(callback); | 465 _requestOrResponse._streamSetErrorHandler(callback); |
| 466 } | 466 } |
| 467 | 467 |
| 468 _HttpRequestResponseBase _requestOrResponse; | 468 _HttpRequestResponseBase _requestOrResponse; |
| 469 } | 469 } |
| 470 | 470 |
| 471 | 471 |
| 472 class _HttpConnectionBase implements Hashable { | 472 class _HttpConnectionBase implements Hashable { |
| 473 static final int PHASE_IDLE = 0; | 473 _HttpConnectionBase() : _sendBuffers = new Queue(), |
| 474 static final int PHASE_REQUEST = 1; | |
| 475 static final int PHASE_RESPONSE = 2; | |
| 476 | |
| 477 _HttpConnectionBase() : _phase = PHASE_IDLE, | |
| 478 _sendBuffers = new Queue(), | |
| 479 _httpParser = new _HttpParser(); | 474 _httpParser = new _HttpParser(); |
| 480 | 475 |
| 481 void _connectionEstablished(Socket socket) { | 476 void _connectionEstablished(Socket socket) { |
| 482 _socket = socket; | 477 _socket = socket; |
| 483 // Register handler for socket events. | 478 // Register handler for socket events. |
| 484 _socket.onData = _onData; | 479 _socket.onData = _onData; |
| 485 _socket.onClosed = _onClosed; | 480 _socket.onClosed = _onClosed; |
| 486 _socket.onError = _onError; | 481 _socket.onError = _onError; |
| 487 } | 482 } |
| 488 | 483 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 501 if (bytesRead > 0) { | 496 if (bytesRead > 0) { |
| 502 int parsed = _httpParser.writeList(buffer, 0, bytesRead); | 497 int parsed = _httpParser.writeList(buffer, 0, bytesRead); |
| 503 if (parsed != bytesRead) { | 498 if (parsed != bytesRead) { |
| 504 // TODO(sgjesse): Error handling. | 499 // TODO(sgjesse): Error handling. |
| 505 _socket.close(); | 500 _socket.close(); |
| 506 } | 501 } |
| 507 } | 502 } |
| 508 } | 503 } |
| 509 | 504 |
| 510 void _onClosed() { | 505 void _onClosed() { |
| 511 if (_phase != PHASE_IDLE) { | 506 _onConnectionClosed(null); |
|
Anders Johnsen
2012/04/02 13:55:35
This is really neat, I like how onError and onClos
| |
| 512 // Client closed socket for writing. Socket should still be open | |
| 513 // for writing the response. | |
| 514 _closing = true; | |
| 515 } else { | |
| 516 // The connection is currently not used by any request just close it. | |
| 517 _socket.close(); | |
| 518 } | |
| 519 if (_onDisconnectCallback != null) _onDisconnectCallback(); | |
| 520 } | 507 } |
| 521 | 508 |
| 522 void _onError(Exception e) { | 509 void _onError(Exception e) { |
| 523 // If an error occurs, make sure to close the socket if one is associated. | 510 // If an error occurs, make sure to close the socket if one is associated. |
| 511 _error = true; | |
| 524 if (_socket != null) { | 512 if (_socket != null) { |
| 525 _socket.close(); | 513 _socket.close(); |
| 526 } | 514 } |
| 527 if (_onErrorCallback != null) { | 515 _onConnectionClosed(e); |
| 528 _onErrorCallback(e); | |
| 529 } | |
| 530 _propagateError(e); | |
| 531 } | 516 } |
| 532 | 517 |
| 533 abstract void _propagateError(Exception e); | 518 abstract void _onConnectionClosed(Exception e); |
| 534 | 519 abstract void _responseDone(); |
| 535 void set onDisconnect(void callback()) { | |
| 536 _onDisconnectCallback = callback; | |
| 537 } | |
| 538 | |
| 539 void set onError(void callback(Exception e)) { | |
| 540 _onErrorCallback = callback; | |
| 541 } | |
| 542 | 520 |
| 543 int hashCode() => _socket.hashCode(); | 521 int hashCode() => _socket.hashCode(); |
| 544 | 522 |
| 545 int _phase; | |
| 546 Socket _socket; | 523 Socket _socket; |
| 547 bool _closing = false; // Is the socket closed by the client? | 524 bool _closing = false; // Is the socket closed by the client? |
| 525 bool _error = false; // Is the socket closed due to an error? | |
| 548 _HttpParser _httpParser; | 526 _HttpParser _httpParser; |
| 549 | 527 |
| 550 Queue _sendBuffers; | 528 Queue _sendBuffers; |
| 551 | |
| 552 Function _onDisconnectCallback; | |
| 553 Function _onErrorCallback; | |
| 554 } | 529 } |
| 555 | 530 |
| 556 | 531 |
| 557 // HTTP server connection over a socket. | 532 // HTTP server connection over a socket. |
| 558 class _HttpConnection extends _HttpConnectionBase { | 533 class _HttpConnection extends _HttpConnectionBase { |
| 559 _HttpConnection(HttpServer this._server) { | 534 _HttpConnection(HttpServer this._server) { |
| 560 // Register HTTP parser callbacks. | 535 // Register HTTP parser callbacks. |
| 561 _httpParser.requestStart = | 536 _httpParser.requestStart = |
| 562 (method, uri) => _onRequestStart(method, uri); | 537 (method, uri) => _onRequestStart(method, uri); |
| 563 _httpParser.responseStart = | 538 _httpParser.responseStart = |
| 564 (statusCode, reasonPhrase) => | 539 (statusCode, reasonPhrase) => |
| 565 _onResponseStart(statusCode, reasonPhrase); | 540 _onResponseStart(statusCode, reasonPhrase); |
| 566 _httpParser.headerReceived = | 541 _httpParser.headerReceived = |
| 567 (name, value) => _onHeaderReceived(name, value); | 542 (name, value) => _onHeaderReceived(name, value); |
| 568 _httpParser.headersComplete = () => _onHeadersComplete(); | 543 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 569 _httpParser.dataReceived = (data) => _onDataReceived(data); | 544 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 570 _httpParser.dataEnd = () => _onDataEnd(); | 545 _httpParser.dataEnd = (close) => _onDataEnd(close); |
| 571 _httpParser.error = (e) => _onError(e); | 546 _httpParser.error = (e) => _onError(e); |
| 572 } | 547 } |
| 573 | 548 |
| 549 void _onConnectionClosed(Exception e) { | |
| 550 // Socket is closed either due to an error or due to normal socket close. | |
| 551 if (e != null && onError != null) { | |
|
Anders Johnsen
2012/04/02 13:55:35
Do we want to signal onError before or after takin
Søren Gjesse
2012/04/02 14:11:33
I think doing it here is fine. I moved the stream
| |
| 552 onError(e); | |
| 553 } | |
| 554 | |
| 555 // If currently not processing any request just close the socket. | |
| 556 if (_httpParser.isIdle) { | |
| 557 _socket.close(); | |
| 558 if (onClosed != null) { | |
|
Anders Johnsen
2012/04/02 13:55:35
Here we can end up calling both onError and onClos
Søren Gjesse
2012/04/02 14:11:33
Good point. Changed so that either onError or onCl
| |
| 559 onClosed(); | |
| 560 } | |
| 561 return; | |
| 562 } | |
| 563 | |
| 564 // Processing a request. | |
| 565 if (e != null) { | |
| 566 // Propagate the error to the streams. | |
| 567 if (_request != null && _request._streamErrorHandler != null) { | |
| 568 _request._streamErrorHandler(e); | |
| 569 } | |
| 570 if (_response != null && _response._streamErrorHandler != null) { | |
| 571 _response._streamErrorHandler(e); | |
| 572 } | |
| 573 } else { | |
| 574 // Indicate connection close to the HTTP parser. | |
| 575 _httpParser.connectionClosed(); | |
| 576 _closing = true; | |
| 577 } | |
| 578 } | |
| 579 | |
| 574 void _onRequestStart(String method, String uri) { | 580 void _onRequestStart(String method, String uri) { |
| 575 // Create new request and response objects for this request. | 581 // Create new request and response objects for this request. |
| 576 _phase = PHASE_REQUEST; | |
| 577 _request = new _HttpRequest(this); | 582 _request = new _HttpRequest(this); |
| 578 _response = new _HttpResponse(this); | 583 _response = new _HttpResponse(this); |
| 579 _request._onRequestStart(method, uri); | 584 _request._onRequestStart(method, uri); |
| 580 } | 585 } |
| 581 | 586 |
| 582 void _onResponseStart(int statusCode, String reasonPhrase) { | 587 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 583 // TODO(sgjesse): Error handling. | 588 // TODO(sgjesse): Error handling. |
| 584 } | 589 } |
| 585 | 590 |
| 586 void _onHeaderReceived(String name, String value) { | 591 void _onHeaderReceived(String name, String value) { |
| 587 _request._onHeaderReceived(name, value); | 592 _request._onHeaderReceived(name, value); |
| 588 } | 593 } |
| 589 | 594 |
| 590 void _onHeadersComplete() { | 595 void _onHeadersComplete() { |
| 591 _request._onHeadersComplete(); | 596 _request._onHeadersComplete(); |
| 592 _response.keepAlive = _httpParser.keepAlive; | 597 _response.keepAlive = _httpParser.keepAlive; |
| 593 if (requestReceived != null) { | 598 if (onRequestReceived != null) { |
| 594 requestReceived(_request, _response); | 599 onRequestReceived(_request, _response); |
| 595 } | 600 } |
| 596 } | 601 } |
| 597 | 602 |
| 598 void _onDataReceived(List<int> data) { | 603 void _onDataReceived(List<int> data) { |
| 599 _request._onDataReceived(data); | 604 _request._onDataReceived(data); |
| 600 } | 605 } |
| 601 | 606 |
| 602 void _onDataEnd() { | 607 void _onDataEnd(bool close) { |
| 603 // Phase might already have gone to PHASE_IDLE if the response is | 608 if (_request != null) { |
| 604 // sent without waiting for request body. | 609 _request._onDataEnd(); |
| 605 if (_phase == PHASE_REQUEST) { | |
| 606 _phase = PHASE_RESPONSE; | |
| 607 } | 610 } |
| 608 _request._onDataEnd(); | 611 _request = null; |
| 609 } | 612 } |
| 610 | 613 |
| 611 void _propagateError(Exception e) { | 614 void _responseDone() { |
| 612 if (_request != null && _request._streamErrorHandler != null) { | 615 // If the connection is closing then close the output stream to |
| 613 _request._streamErrorHandler(e); | 616 // fully close the socket. |
| 617 if (_closing) { | |
| 618 outputStream.close(); | |
| 614 } | 619 } |
| 615 if (_response != null && _response._streamErrorHandler != null) { | 620 _response = null; |
| 616 _response._streamErrorHandler(e); | |
| 617 } | |
| 618 } | 621 } |
| 619 | 622 |
| 620 HttpServer _server; | 623 HttpServer _server; |
| 621 HttpRequest _request; | 624 HttpRequest _request; |
| 622 HttpResponse _response; | 625 HttpResponse _response; |
| 623 | 626 |
| 624 // Callbacks. | 627 // Callbacks. |
| 625 var requestReceived; | 628 Function onRequestReceived; |
| 629 Function onClosed; | |
| 630 Function onError; | |
| 626 } | 631 } |
| 627 | 632 |
| 628 | 633 |
| 629 // HTTP server waiting for socket connections. The connections are | 634 // HTTP server waiting for socket connections. The connections are |
| 630 // managed by the server and as requests are received the request. | 635 // managed by the server and as requests are received the request. |
| 631 class _HttpServer implements HttpServer { | 636 class _HttpServer implements HttpServer { |
| 632 _HttpServer() : _connections = new Set<_HttpConnection>(); | 637 _HttpServer() : _connections = new Set<_HttpConnection>(); |
| 633 | 638 |
| 634 void listen(String host, int port, [int backlog = 5]) { | 639 void listen(String host, int port, [int backlog = 5]) { |
| 635 listenOn(new ServerSocket(host, port, backlog)); | 640 listenOn(new ServerSocket(host, port, backlog)); |
| 636 _closeServer = true; | 641 _closeServer = true; |
| 637 } | 642 } |
| 638 | 643 |
| 639 void listenOn(ServerSocket serverSocket) { | 644 void listenOn(ServerSocket serverSocket) { |
| 640 void onConnection(Socket socket) { | 645 void onConnection(Socket socket) { |
| 641 // Accept the client connection. | 646 // Accept the client connection. |
| 642 _HttpConnection connection = new _HttpConnection(this); | 647 _HttpConnection connection = new _HttpConnection(this); |
| 643 connection.requestReceived = _onRequest; | 648 connection._connectionEstablished(socket); |
| 644 connection.onDisconnect = () => _connections.remove(connection); | 649 connection.onRequestReceived = _onRequest; |
| 650 connection.onClosed = () => _connections.remove(connection); | |
| 645 connection.onError = (e) { | 651 connection.onError = (e) { |
| 646 if (_onError != null) _onError(e); | 652 if (_onError != null) _onError(e); |
| 647 }; | 653 }; |
| 648 connection._connectionEstablished(socket); | 654 connection._connectionEstablished(socket); |
| 649 _connections.add(connection); | 655 _connections.add(connection); |
| 650 } | 656 } |
| 651 serverSocket.onConnection = onConnection; | 657 serverSocket.onConnection = onConnection; |
| 652 _server = serverSocket; | 658 _server = serverSocket; |
| 653 _closeServer = false; | 659 _closeServer = false; |
| 654 } | 660 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 772 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 767 return _writeList(buffer, offset, len); | 773 return _writeList(buffer, offset, len); |
| 768 } | 774 } |
| 769 | 775 |
| 770 void _streamClose() { | 776 void _streamClose() { |
| 771 _state = DONE; | 777 _state = DONE; |
| 772 // Stop tracking no pending write events. | 778 // Stop tracking no pending write events. |
| 773 _httpConnection.outputStream.onNoPendingWrites = null; | 779 _httpConnection.outputStream.onNoPendingWrites = null; |
| 774 // Ensure that any trailing data is written. | 780 // Ensure that any trailing data is written. |
| 775 _writeDone(); | 781 _writeDone(); |
| 776 // If the connection is closing then close the output stream to | |
| 777 // fully close the socket. | |
| 778 if (_httpConnection._closing) { | |
| 779 _httpConnection.outputStream.close(); | |
| 780 } | |
| 781 } | 782 } |
| 782 | 783 |
| 783 void _streamSetNoPendingWriteHandler(callback()) { | 784 void _streamSetNoPendingWriteHandler(callback()) { |
| 784 if (_state != DONE) { | 785 if (_state != DONE) { |
| 785 _httpConnection.outputStream.onNoPendingWrites = callback; | 786 _httpConnection.outputStream.onNoPendingWrites = callback; |
| 786 } | 787 } |
| 787 } | 788 } |
| 788 | 789 |
| 789 void _streamSetCloseHandler(callback()) { | 790 void _streamSetCloseHandler(callback()) { |
| 790 // TODO(sgjesse): Handle this. | 791 // TODO(sgjesse): Handle this. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 880 } | 881 } |
| 881 } | 882 } |
| 882 | 883 |
| 883 void _onDataReceived(List<int> data) { | 884 void _onDataReceived(List<int> data) { |
| 884 _buffer.add(data); | 885 _buffer.add(data); |
| 885 if (_inputStream != null) _inputStream._dataReceived(); | 886 if (_inputStream != null) _inputStream._dataReceived(); |
| 886 } | 887 } |
| 887 | 888 |
| 888 void _onDataEnd() { | 889 void _onDataEnd() { |
| 889 if (_inputStream != null) _inputStream._closeReceived(); | 890 if (_inputStream != null) _inputStream._closeReceived(); |
| 891 _connection._responseDone(); | |
| 890 } | 892 } |
| 891 | 893 |
| 892 // Delegate functions for the HttpInputStream implementation. | 894 // Delegate functions for the HttpInputStream implementation. |
| 893 int _streamAvailable() { | 895 int _streamAvailable() { |
| 894 return _buffer.length; | 896 return _buffer.length; |
| 895 } | 897 } |
| 896 | 898 |
| 897 List<int> _streamRead(int bytesToRead) { | 899 List<int> _streamRead(int bytesToRead) { |
| 898 return _buffer.readBytes(bytesToRead); | 900 return _buffer.readBytes(bytesToRead); |
| 899 } | 901 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 928 // Register HTTP parser callbacks. | 930 // Register HTTP parser callbacks. |
| 929 _httpParser.requestStart = | 931 _httpParser.requestStart = |
| 930 (method, uri) => _onRequestStart(method, uri); | 932 (method, uri) => _onRequestStart(method, uri); |
| 931 _httpParser.responseStart = | 933 _httpParser.responseStart = |
| 932 (statusCode, reasonPhrase) => | 934 (statusCode, reasonPhrase) => |
| 933 _onResponseStart(statusCode, reasonPhrase); | 935 _onResponseStart(statusCode, reasonPhrase); |
| 934 _httpParser.headerReceived = | 936 _httpParser.headerReceived = |
| 935 (name, value) => _onHeaderReceived(name, value); | 937 (name, value) => _onHeaderReceived(name, value); |
| 936 _httpParser.headersComplete = () => _onHeadersComplete(); | 938 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 937 _httpParser.dataReceived = (data) => _onDataReceived(data); | 939 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 938 _httpParser.dataEnd = () => _onDataEnd(); | 940 _httpParser.dataEnd = (closed) => _onDataEnd(closed); |
| 939 _httpParser.error = (e) => _onError(e); | 941 _httpParser.error = (e) => _onError(e); |
| 940 // Tell the HTTP parser the method it is expecting a response to. | 942 // Tell the HTTP parser the method it is expecting a response to. |
| 941 _httpParser.responseToMethod = _method; | 943 _httpParser.responseToMethod = _method; |
| 942 | |
| 943 onDisconnect = _onDisconnected; | |
| 944 } | 944 } |
| 945 | 945 |
| 946 void _propagateError(Exception e) { | 946 void _responseDone() { |
| 947 if (_response != null && _response._streamErrorHandler != null) { | 947 if (_closing) { |
| 948 _response._streamErrorHandler(e); | 948 if (_socket != null) { |
| 949 _socket.close(); | |
| 950 } | |
| 951 } else { | |
| 952 _client._returnSocketConnection(_socketConn); | |
| 949 } | 953 } |
| 954 _socket = null; | |
| 955 _socketConn = null; | |
| 950 } | 956 } |
| 951 | 957 |
| 952 HttpClientRequest open(String method, String uri) { | 958 HttpClientRequest open(String method, String uri) { |
| 953 _method = method; | 959 _method = method; |
| 954 _request = new _HttpClientRequest(method, uri, this); | 960 _request = new _HttpClientRequest(method, uri, this); |
| 955 _request.keepAlive = true; | 961 _request.keepAlive = true; |
| 956 _response = new _HttpClientResponse(this); | 962 _response = new _HttpClientResponse(this); |
| 957 return _request; | 963 return _request; |
| 958 } | 964 } |
| 959 | 965 |
| 966 void _onConnectionClosed(Exception e) { | |
| 967 // Socket is closed either due to an error or due to normal socket close. | |
| 968 if (e != null) { | |
| 969 if (_onErrorCallback != null) { | |
| 970 _onErrorCallback(e); | |
| 971 } | |
| 972 } | |
| 973 _closing = true; | |
| 974 if (e != null) { | |
| 975 // Propagate the error to the streams. | |
| 976 if (_response != null && _response._streamErrorHandler != null) { | |
| 977 _response._streamErrorHandler(e); | |
| 978 } | |
| 979 _responseDone(); | |
| 980 } else { | |
| 981 // If there was no socket error the socket was closed | |
| 982 // normally. Indicate closing to the HTTP Parser as there might | |
| 983 // still be an HTTP error. | |
| 984 _httpParser.connectionClosed(); | |
| 985 } | |
| 986 } | |
| 987 | |
| 960 void _onRequestStart(String method, String uri) { | 988 void _onRequestStart(String method, String uri) { |
| 961 // TODO(sgjesse): Error handling. | 989 // TODO(sgjesse): Error handling. |
| 962 } | 990 } |
| 963 | 991 |
| 964 void _onResponseStart(int statusCode, String reasonPhrase) { | 992 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 965 _response._onResponseStart(statusCode, reasonPhrase); | 993 _response._onResponseStart(statusCode, reasonPhrase); |
| 966 } | 994 } |
| 967 | 995 |
| 968 void _onHeaderReceived(String name, String value) { | 996 void _onHeaderReceived(String name, String value) { |
| 969 _response._onHeaderReceived(name, value); | 997 _response._onHeaderReceived(name, value); |
| 970 } | 998 } |
| 971 | 999 |
| 972 void _onHeadersComplete() { | 1000 void _onHeadersComplete() { |
| 973 _response._onHeadersComplete(); | 1001 _response._onHeadersComplete(); |
| 974 } | 1002 } |
| 975 | 1003 |
| 976 void _onDataReceived(List<int> data) { | 1004 void _onDataReceived(List<int> data) { |
| 977 _response._onDataReceived(data); | 1005 _response._onDataReceived(data); |
| 978 } | 1006 } |
| 979 | 1007 |
| 980 void _onDataEnd() { | 1008 void _onDataEnd(bool close) { |
| 981 onDisconnect = null; | 1009 if (close) _closing = true; |
| 982 if (_response.headers["connection"] == "close") { | |
| 983 _socket.close(); | |
| 984 } else { | |
| 985 _client._returnSocketConnection(_socketConn); | |
| 986 } | |
| 987 _socket = null; | |
| 988 _socketConn = null; | |
| 989 _response._onDataEnd(); | 1010 _response._onDataEnd(); |
| 990 } | 1011 } |
| 991 | 1012 |
| 992 void set onRequest(void handler(HttpClientRequest request)) { | 1013 void set onRequest(void handler(HttpClientRequest request)) { |
| 993 _onRequest = handler; | 1014 _onRequest = handler; |
| 994 } | 1015 } |
| 995 | 1016 |
| 996 void set onResponse(void handler(HttpClientResponse response)) { | 1017 void set onResponse(void handler(HttpClientResponse response)) { |
| 997 _onResponse = handler; | 1018 _onResponse = handler; |
| 998 } | 1019 } |
| 999 | 1020 |
| 1000 void _onDisconnected() { | 1021 void set onError(void callback(Exception e)) { |
| 1001 if (_onErrorCallback !== null) { | 1022 _onErrorCallback = callback; |
| 1002 _onErrorCallback(new HttpException( | |
| 1003 "Client disconnected before response was received.")); | |
| 1004 } | |
| 1005 } | 1023 } |
| 1006 | 1024 |
| 1007 Function _onRequest; | 1025 Function _onRequest; |
| 1008 Function _onResponse; | 1026 Function _onResponse; |
| 1027 Function _onErrorCallback; | |
| 1009 | 1028 |
| 1010 _HttpClient _client; | 1029 _HttpClient _client; |
| 1011 _SocketConnection _socketConn; | 1030 _SocketConnection _socketConn; |
| 1012 HttpClientRequest _request; | 1031 HttpClientRequest _request; |
| 1013 HttpClientResponse _response; | 1032 HttpClientResponse _response; |
| 1014 String _method; | 1033 String _method; |
| 1015 | 1034 |
| 1016 // Callbacks. | 1035 // Callbacks. |
| 1017 var requestReceived; | 1036 var requestReceived; |
| 1018 } | 1037 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1209 sockets.addFirst(socketConn); | 1228 sockets.addFirst(socketConn); |
| 1210 socketConn._markReturned(); | 1229 socketConn._markReturned(); |
| 1211 } | 1230 } |
| 1212 | 1231 |
| 1213 Function _onOpen; | 1232 Function _onOpen; |
| 1214 Map<String, Queue<_SocketConnection>> _openSockets; | 1233 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1215 Set<_SocketConnection> _activeSockets; | 1234 Set<_SocketConnection> _activeSockets; |
| 1216 Timer _evictionTimer; | 1235 Timer _evictionTimer; |
| 1217 bool _shutdown; // Has this HTTP client been shutdown? | 1236 bool _shutdown; // Has this HTTP client been shutdown? |
| 1218 } | 1237 } |
| OLD | NEW |