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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 case HttpStatus.SERVICE_UNAVAILABLE: return "Service Unavailable"; | 347 case HttpStatus.SERVICE_UNAVAILABLE: return "Service Unavailable"; |
| 348 case HttpStatus.GATEWAY_TIMEOUT: return "Gateway Time-out"; | 348 case HttpStatus.GATEWAY_TIMEOUT: return "Gateway Time-out"; |
| 349 case HttpStatus.HTTP_VERSION_NOT_SUPPORTED: | 349 case HttpStatus.HTTP_VERSION_NOT_SUPPORTED: |
| 350 return "Http Version not supported"; | 350 return "Http Version not supported"; |
| 351 default: return "Status $statusCode"; | 351 default: return "Status $statusCode"; |
| 352 } | 352 } |
| 353 } | 353 } |
| 354 | 354 |
| 355 bool _writeHeader() { | 355 bool _writeHeader() { |
| 356 List<int> data; | 356 List<int> data; |
| 357 OutputStream stream = _httpConnection.outputStream; | |
| 358 | 357 |
| 359 // Write status line. | 358 // Write status line. |
| 360 stream.write(_Const.HTTP11); | 359 _httpConnection.outputStream.write(_Const.HTTP11); |
| 361 _writeSP(); | 360 _writeSP(); |
| 362 data = _statusCode.toString().charCodes(); | 361 data = _statusCode.toString().charCodes(); |
| 363 stream.write(data); | 362 _httpConnection.outputStream.write(data); |
| 364 _writeSP(); | 363 _writeSP(); |
| 365 data = reasonPhrase.charCodes(); | 364 data = reasonPhrase.charCodes(); |
| 366 stream.write(data); | 365 _httpConnection.outputStream.write(data); |
| 367 _writeCRLF(); | 366 _writeCRLF(); |
| 368 | 367 |
| 369 // Determine the value of the "Connection" header | 368 // Determine the value of the "Connection" header |
| 370 // based on the keep alive state. | 369 // based on the keep alive state. |
| 371 setHeader("Connection", keepAlive ? "keep-alive" : "close"); | 370 setHeader("Connection", keepAlive ? "keep-alive" : "close"); |
| 372 // Determine the value of the "Transfer-Encoding" header based on | 371 // Determine the value of the "Transfer-Encoding" header based on |
| 373 // whether the content length is known. | 372 // whether the content length is known. |
| 374 if (_contentLength >= 0) { | 373 if (_contentLength >= 0) { |
| 375 setHeader("Content-Length", _contentLength.toString()); | 374 setHeader("Content-Length", _contentLength.toString()); |
| 376 } else { | 375 } else { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 void set onClosed(void callback()) { | 459 void set onClosed(void callback()) { |
| 461 _requestOrResponse._streamSetCloseHandler(callback); | 460 _requestOrResponse._streamSetCloseHandler(callback); |
| 462 } | 461 } |
| 463 | 462 |
| 464 void set onError(void callback(Exception e)) { | 463 void set onError(void callback(Exception e)) { |
| 465 _requestOrResponse._streamSetErrorHandler(callback); | 464 _requestOrResponse._streamSetErrorHandler(callback); |
| 466 } | 465 } |
| 467 | 466 |
| 468 _HttpRequestResponseBase _requestOrResponse; | 467 _HttpRequestResponseBase _requestOrResponse; |
| 469 } | 468 } |
| 470 | 469 |
|
Søren Gjesse
2012/04/02 07:32:41
Looks as if this change is mixed with the previous
Anders Johnsen
2012/04/02 07:36:52
Removed :)
| |
| 470 class _EmptyOutputStream implements OutputStream { | |
| 471 void close() {} | |
| 472 void destroy() {} | |
| 473 | |
| 474 void set onVlosed(void callback()) {} | |
| 475 void set onError(void callback()) {} | |
| 476 void set onNoPendingWrites(void callback()) {} | |
| 477 | |
| 478 bool write(List buffer, [bool copybuffer]) => true; | |
| 479 bool writeFrom(List buffer, [int offset, int len]) => true; | |
| 480 bool writeString(String string, [Encoding encoding]) => true; | |
| 481 } | |
| 471 | 482 |
| 472 class _HttpConnectionBase implements Hashable { | 483 class _HttpConnectionBase implements Hashable { |
| 473 static final int PHASE_IDLE = 0; | 484 static final int PHASE_IDLE = 0; |
| 474 static final int PHASE_REQUEST = 1; | 485 static final int PHASE_REQUEST = 1; |
| 475 static final int PHASE_RESPONSE = 2; | 486 static final int PHASE_RESPONSE = 2; |
| 476 | 487 |
| 477 _HttpConnectionBase() : _phase = PHASE_IDLE, | 488 _HttpConnectionBase() : _phase = PHASE_IDLE, |
| 478 _sendBuffers = new Queue(), | 489 _sendBuffers = new Queue(), |
| 479 _httpParser = new _HttpParser(); | 490 _httpParser = new _HttpParser(); |
| 480 | 491 |
| 481 void _connectionEstablished(Socket socket) { | 492 void _connectionEstablished(Socket socket) { |
| 482 _socket = socket; | 493 _socket = socket; |
| 483 // Register handler for socket events. | 494 // Register handler for socket events. |
| 484 _socket.onData = _onData; | 495 _socket.onData = _onData; |
| 485 _socket.onClosed = _onClosed; | 496 _socket.onClosed = _onClosed; |
| 486 _socket.onError = _onError; | 497 _socket.onError = _onError; |
| 487 } | 498 } |
| 488 | 499 |
| 489 OutputStream get outputStream() { | 500 OutputStream get outputStream() { |
| 501 if (_closing) return new _EmptyOutputStream(); | |
| 490 return _socket.outputStream; | 502 return _socket.outputStream; |
| 491 } | 503 } |
| 492 | 504 |
| 493 void _onData() { | 505 void _onData() { |
| 494 int available = _socket.available(); | 506 int available = _socket.available(); |
| 495 if (available == 0) { | 507 if (available == 0) { |
| 496 return; | 508 return; |
| 497 } | 509 } |
| 498 | 510 |
| 499 ByteArray buffer = new ByteArray(available); | 511 ByteArray buffer = new ByteArray(available); |
| 500 int bytesRead = _socket.readList(buffer, 0, available); | 512 int bytesRead = _socket.readList(buffer, 0, available); |
| 501 if (bytesRead > 0) { | 513 if (bytesRead > 0) { |
| 502 int parsed = _httpParser.writeList(buffer, 0, bytesRead); | 514 int parsed = _httpParser.writeList(buffer, 0, bytesRead); |
| 503 if (parsed != bytesRead) { | 515 if (parsed != bytesRead) { |
| 504 // TODO(sgjesse): Error handling. | 516 // TODO(sgjesse): Error handling. |
| 505 _socket.close(); | 517 _socket.close(); |
| 506 } | 518 } |
| 507 } | 519 } |
| 508 } | 520 } |
| 509 | 521 |
| 510 void _onClosed() { | 522 void _onClosed() { |
| 523 _closing = true; | |
| 511 if (_phase != PHASE_IDLE) { | 524 if (_phase != PHASE_IDLE) { |
| 512 // Client closed socket for writing. Socket should still be open | 525 // Client closed socket for writing. Socket should still be open |
| 513 // for writing the response. | 526 // for writing the response. |
| 514 _closing = true; | |
| 515 } else { | 527 } else { |
| 516 // The connection is currently not used by any request just close it. | 528 // The connection is currently not used by any request just close it. |
| 517 _socket.close(); | 529 _socket.close(); |
| 518 } | 530 } |
| 519 if (_onDisconnectCallback != null) _onDisconnectCallback(); | 531 if (_onDisconnectCallback != null) _onDisconnectCallback(); |
| 520 } | 532 } |
| 521 | 533 |
| 522 void _onError(Exception e) { | 534 void _onError(Exception e) { |
| 535 _closing = true; | |
| 523 // If an error occurs, make sure to close the socket if one is associated. | 536 // If an error occurs, make sure to close the socket if one is associated. |
| 524 if (_socket != null) { | 537 if (_socket != null) { |
| 525 _socket.close(); | 538 _socket.close(); |
| 526 } | 539 } |
| 527 if (_onErrorCallback != null) { | 540 if (_onErrorCallback != null) { |
| 528 _onErrorCallback(e); | 541 _onErrorCallback(e); |
| 529 } | 542 } |
| 530 _propagateError(e); | 543 _propagateError(e); |
| 531 } | 544 } |
| 532 | 545 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 HttpResponse _response; | 635 HttpResponse _response; |
| 623 | 636 |
| 624 // Callbacks. | 637 // Callbacks. |
| 625 var requestReceived; | 638 var requestReceived; |
| 626 } | 639 } |
| 627 | 640 |
| 628 | 641 |
| 629 // HTTP server waiting for socket connections. The connections are | 642 // HTTP server waiting for socket connections. The connections are |
| 630 // managed by the server and as requests are received the request. | 643 // managed by the server and as requests are received the request. |
| 631 class _HttpServer implements HttpServer { | 644 class _HttpServer implements HttpServer { |
| 645 _HttpServer() : | |
| 646 _connections = new Set<_HttpConnection>(); | |
| 647 | |
| 632 void listen(String host, int port, [int backlog = 5]) { | 648 void listen(String host, int port, [int backlog = 5]) { |
| 649 _server = new ServerSocket(host, port, backlog); | |
| 650 attachTo(_server); | |
| 651 } | |
| 633 | 652 |
| 653 void attachTo(ServerSocket serverSocket) { | |
| 634 void onConnection(Socket socket) { | 654 void onConnection(Socket socket) { |
| 635 // Accept the client connection. | 655 // Accept the client connection. |
| 636 _HttpConnection connection = new _HttpConnection(this); | 656 _HttpConnection connection = new _HttpConnection(this); |
| 637 connection._connectionEstablished(socket); | |
| 638 connection.requestReceived = _onRequest; | 657 connection.requestReceived = _onRequest; |
| 639 _connections.add(connection); | |
| 640 connection.onDisconnect = () => _connections.remove(connection); | 658 connection.onDisconnect = () => _connections.remove(connection); |
| 641 connection.onError = (e) { | 659 connection.onError = (e) { |
| 642 if (_onError != null) _onError(e); | 660 if (_onError != null) _onError(e); |
| 643 }; | 661 }; |
| 662 connection._connectionEstablished(socket); | |
| 663 _connections.add(connection); | |
| 644 } | 664 } |
| 645 | 665 |
| 646 _connections = new Set<_HttpConnection>(); | 666 serverSocket.onConnection = onConnection; |
| 647 _server = new ServerSocket(host, port, backlog); | |
| 648 _server.onConnection = onConnection; | |
| 649 } | 667 } |
| 650 | 668 |
| 651 void close() { | 669 void close() { |
| 652 _server.close(); | 670 if (_server !== null) { |
| 671 _server.close(); | |
| 672 _server = null; | |
| 673 } | |
| 653 for (_HttpConnection connection in _connections) { | 674 for (_HttpConnection connection in _connections) { |
| 654 connection._socket.close(); | 675 connection._socket.close(); |
| 655 } | 676 } |
| 677 _connections.clear(); | |
| 656 } | 678 } |
| 657 | 679 |
| 658 int get port() => _server.port; | 680 int get port() => _server.port; |
| 659 | 681 |
| 660 void set onError(void callback(Exception e)) { | 682 void set onError(void callback(Exception e)) { |
| 661 _onError = callback; | 683 _onError = callback; |
| 662 } | 684 } |
| 663 | 685 |
| 664 void set onRequest(void callback(HttpRequest, HttpResponse)) { | 686 void set onRequest(void callback(HttpRequest, HttpResponse)) { |
| 665 _onRequest = callback; | 687 _onRequest = callback; |
| 666 } | 688 } |
| 667 | 689 |
| 668 ServerSocket _server; // The server listen socket. | 690 ServerSocket _server; // The server listen socket, if created internally. |
| 669 Set<_HttpConnection> _connections; // Set of currently connected clients. | 691 Set<_HttpConnection> _connections; // Set of currently connected clients. |
| 670 Function _onRequest; | 692 Function _onRequest; |
| 671 Function _onError; | 693 Function _onError; |
| 672 } | 694 } |
| 673 | 695 |
| 674 | 696 |
| 675 class _HttpClientRequest | 697 class _HttpClientRequest |
| 676 extends _HttpRequestResponseBase implements HttpClientRequest { | 698 extends _HttpRequestResponseBase implements HttpClientRequest { |
| 677 static final int START = 0; | 699 static final int START = 0; |
| 678 static final int HEADERS_SENT = 1; | 700 static final int HEADERS_SENT = 1; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 774 void _streamSetCloseHandler(callback()) { | 796 void _streamSetCloseHandler(callback()) { |
| 775 // TODO(sgjesse): Handle this. | 797 // TODO(sgjesse): Handle this. |
| 776 } | 798 } |
| 777 | 799 |
| 778 void _streamSetErrorHandler(callback(Exception e)) { | 800 void _streamSetErrorHandler(callback(Exception e)) { |
| 779 _streamErrorHandler = callback; | 801 _streamErrorHandler = callback; |
| 780 } | 802 } |
| 781 | 803 |
| 782 void _writeHeader() { | 804 void _writeHeader() { |
| 783 List<int> data; | 805 List<int> data; |
| 784 OutputStream stream = _httpConnection.outputStream; | |
| 785 | 806 |
| 786 // Write request line. | 807 // Write request line. |
| 787 data = _method.toString().charCodes(); | 808 data = _method.toString().charCodes(); |
| 788 stream.write(data); | 809 _httpConnection.outputStream.write(data); |
| 789 _writeSP(); | 810 _writeSP(); |
| 790 data = _uri.toString().charCodes(); | 811 data = _uri.toString().charCodes(); |
| 791 stream.write(data); | 812 _httpConnection.outputStream.write(data); |
| 792 _writeSP(); | 813 _writeSP(); |
| 793 stream.write(_Const.HTTP11); | 814 _httpConnection.outputStream.write(_Const.HTTP11); |
| 794 _writeCRLF(); | 815 _writeCRLF(); |
| 795 | 816 |
| 796 // Determine the value of the "Connection" header | 817 // Determine the value of the "Connection" header |
| 797 // based on the keep alive state. | 818 // based on the keep alive state. |
| 798 setHeader("Connection", keepAlive ? "keep-alive" : "close"); | 819 setHeader("Connection", keepAlive ? "keep-alive" : "close"); |
| 799 // Determine the value of the "Transfer-Encoding" header based on | 820 // Determine the value of the "Transfer-Encoding" header based on |
| 800 // whether the content length is known. | 821 // whether the content length is known. |
| 801 if (_contentLength >= 0) { | 822 if (_contentLength >= 0) { |
| 802 setHeader("Content-Length", _contentLength.toString()); | 823 setHeader("Content-Length", _contentLength.toString()); |
| 803 } else { | 824 } else { |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1194 sockets.addFirst(socketConn); | 1215 sockets.addFirst(socketConn); |
| 1195 socketConn._markReturned(); | 1216 socketConn._markReturned(); |
| 1196 } | 1217 } |
| 1197 | 1218 |
| 1198 Function _onOpen; | 1219 Function _onOpen; |
| 1199 Map<String, Queue<_SocketConnection>> _openSockets; | 1220 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1200 Set<_SocketConnection> _activeSockets; | 1221 Set<_SocketConnection> _activeSockets; |
| 1201 Timer _evictionTimer; | 1222 Timer _evictionTimer; |
| 1202 bool _shutdown; // Has this HTTP client been shutdown? | 1223 bool _shutdown; // Has this HTTP client been shutdown? |
| 1203 } | 1224 } |
| OLD | NEW |